9
9
10
10
// ErrorsConfig represents the top-level errors configuration
11
11
type ErrorsConfig struct {
12
- Retry []* RetryBlock `cty:"retry" hcl:"retry,block"`
13
- Ignore []* IgnoreBlock `cty:"ignore" hcl:"ignore,block"`
12
+ Retry []* RetryBlock `cty:"retry" hcl:"retry,block"`
13
+ Ignore []* IgnoreBlock `cty:"ignore" hcl:"ignore,block"`
14
14
}
15
15
16
16
// RetryBlock represents a labeled retry block
@@ -29,146 +29,169 @@ type IgnoreBlock struct {
29
29
IgnorableErrors []string `cty:"ignorable_errors" hcl:"ignorable_errors"`
30
30
}
31
31
32
- // Clone creates a deep copy of ErrorsConfig
32
+ // Clone returns a deep copy of ErrorsConfig
33
33
func (c * ErrorsConfig ) Clone () * ErrorsConfig {
34
34
if c == nil {
35
35
return nil
36
36
}
37
37
38
- clone := & ErrorsConfig {
39
- Retry : make ([] * RetryBlock , len ( c .Retry ) ),
40
- Ignore : make ([] * IgnoreBlock , len ( c .Ignore ) ),
38
+ return & ErrorsConfig {
39
+ Retry : cloneRetryBlocks ( c .Retry ),
40
+ Ignore : cloneIgnoreBlocks ( c .Ignore ),
41
41
}
42
+ }
42
43
43
- // Clone Retry blocks
44
- for i , retry := range c .Retry {
45
- clone .Retry [i ] = retry .Clone ()
44
+ // Merge combines the current ErrorsConfig with another one, prioritizing the other config
45
+ func (c * ErrorsConfig ) Merge (other * ErrorsConfig ) {
46
+ if c == nil || other == nil {
47
+ return
46
48
}
47
49
48
- // Clone Ignore blocks
49
- for i , ignore := range c .Ignore {
50
- clone .Ignore [i ] = ignore .Clone ()
50
+ c .Retry = mergeRetryBlocks (c .Retry , other .Retry )
51
+ c .Ignore = mergeIgnoreBlocks (c .Ignore , other .Ignore )
52
+ }
53
+
54
+ // Clone returns a deep copy of a RetryBlock
55
+ func (r * RetryBlock ) Clone () * RetryBlock {
56
+ if r == nil {
57
+ return nil
51
58
}
52
59
53
- return clone
60
+ return & RetryBlock {
61
+ Label : r .Label ,
62
+ RetryableErrors : cloneStringSlice (r .RetryableErrors ),
63
+ MaxAttempts : r .MaxAttempts ,
64
+ SleepIntervalSec : r .SleepIntervalSec ,
65
+ }
54
66
}
55
67
56
- // Merge combines the current ErrorsConfig with another one, with the other config taking precedence
57
- func (c * ErrorsConfig ) Merge ( other * ErrorsConfig ) {
58
- if other == nil {
59
- return
68
+ // Clone returns a deep copy of an IgnoreBlock
69
+ func (i * IgnoreBlock ) Clone () * IgnoreBlock {
70
+ if i == nil {
71
+ return nil
60
72
}
61
73
62
- if c == nil {
63
- * c = * other
64
- return
74
+ return & IgnoreBlock {
75
+ Label : i .Label ,
76
+ IgnorableErrors : cloneStringSlice (i .IgnorableErrors ),
77
+ Message : i .Message ,
78
+ Signals : cloneSignalsMap (i .Signals ),
65
79
}
80
+ }
66
81
67
- retryMap := make (map [string ]* RetryBlock )
68
- for _ , block := range c .Retry {
69
- retryMap [block .Label ] = block
82
+ // Helper function to deep copy a slice of RetryBlock
83
+ func cloneRetryBlocks (blocks []* RetryBlock ) []* RetryBlock {
84
+ if blocks == nil {
85
+ return nil
70
86
}
71
87
72
- ignoreMap := make (map [ string ] * IgnoreBlock )
73
- for _ , block := range c . Ignore {
74
- ignoreMap [ block . Label ] = block
88
+ cloned := make ([] * RetryBlock , len ( blocks ) )
89
+ for i , block := range blocks {
90
+ cloned [ i ] = block . Clone ()
75
91
}
76
92
77
- // Merge retry blocks
78
- for _ , otherBlock := range other .Retry {
79
- if existing , exists := retryMap [otherBlock .Label ]; exists {
80
- existing .RetryableErrors = util .MergeStringSlices (existing .RetryableErrors , otherBlock .RetryableErrors )
81
-
82
- if otherBlock .MaxAttempts > 0 {
83
- existing .MaxAttempts = otherBlock .MaxAttempts
84
- }
93
+ return cloned
94
+ }
85
95
86
- if otherBlock .SleepIntervalSec > 0 {
87
- existing .SleepIntervalSec = otherBlock .SleepIntervalSec
88
- }
89
- } else {
90
- // Add new block
91
- retryMap [otherBlock .Label ] = otherBlock
92
- }
96
+ // Helper function to deep copy a slice of IgnoreBlock
97
+ func cloneIgnoreBlocks (blocks []* IgnoreBlock ) []* IgnoreBlock {
98
+ if blocks == nil {
99
+ return nil
93
100
}
94
101
95
- // Merge ignore blocks
96
- for _ , otherBlock := range other .Ignore {
97
- if existing , exists := ignoreMap [otherBlock .Label ]; exists {
98
- existing .IgnorableErrors = util .MergeStringSlices (existing .IgnorableErrors , otherBlock .IgnorableErrors )
99
-
100
- if otherBlock .Message != "" {
101
- existing .Message = otherBlock .Message
102
- }
102
+ cloned := make ([]* IgnoreBlock , len (blocks ))
103
+ for i , block := range blocks {
104
+ cloned [i ] = block .Clone ()
105
+ }
103
106
104
- if otherBlock .Signals != nil {
105
- if existing .Signals == nil {
106
- existing .Signals = make (map [string ]cty.Value )
107
- }
107
+ return cloned
108
+ }
108
109
109
- maps .Copy (existing .Signals , otherBlock .Signals )
110
- }
111
- } else {
112
- // Add new block
113
- ignoreMap [otherBlock .Label ] = otherBlock
114
- }
110
+ // Helper function to deep copy a slice of strings
111
+ func cloneStringSlice (slice []string ) []string {
112
+ if slice == nil {
113
+ return nil
115
114
}
116
115
117
- // Convert maps back to slices
118
- c .Retry = make ([]* RetryBlock , 0 , len (retryMap ))
119
- for _ , block := range retryMap {
120
- c .Retry = append (c .Retry , block )
121
- }
116
+ cloned := make ([]string , len (slice ))
117
+ copy (cloned , slice )
122
118
123
- c .Ignore = make ([]* IgnoreBlock , 0 , len (ignoreMap ))
124
- for _ , block := range ignoreMap {
125
- c .Ignore = append (c .Ignore , block )
126
- }
119
+ return cloned
127
120
}
128
121
129
- // Clone creates a deep copy of RetryBlock
130
- func ( r * RetryBlock ) Clone () * RetryBlock {
131
- if r == nil {
122
+ // Helper function to deep copy a map of signals
123
+ func cloneSignalsMap ( signals map [ string ]cty. Value ) map [ string ]cty. Value {
124
+ if signals == nil {
132
125
return nil
133
126
}
134
127
135
- clone := & RetryBlock {
136
- Label : r .Label ,
137
- MaxAttempts : r .MaxAttempts ,
138
- SleepIntervalSec : r .SleepIntervalSec ,
128
+ cloned := make (map [string ]cty.Value , len (signals ))
129
+ maps .Copy (cloned , signals )
130
+
131
+ return cloned
132
+ }
133
+
134
+ // Merges two slices of RetryBlock, prioritizing the second slice
135
+ func mergeRetryBlocks (existing , other []* RetryBlock ) []* RetryBlock {
136
+ retryMap := make (map [string ]* RetryBlock , len (existing )+ len (other ))
137
+
138
+ // Add existing retry blocks
139
+ for _ , block := range existing {
140
+ retryMap [block .Label ] = block
139
141
}
140
142
141
- // Deep copy RetryableErrors slice
142
- if r .RetryableErrors != nil {
143
- clone .RetryableErrors = make ([]string , len (r .RetryableErrors ))
144
- copy (clone .RetryableErrors , r .RetryableErrors )
143
+ // Merge retry blocks from 'other'
144
+ for _ , otherBlock := range other {
145
+ if existingBlock , found := retryMap [otherBlock .Label ]; found {
146
+ existingBlock .RetryableErrors = util .MergeStringSlices (existingBlock .RetryableErrors , otherBlock .RetryableErrors )
147
+
148
+ if otherBlock .MaxAttempts > 0 {
149
+ existingBlock .MaxAttempts = otherBlock .MaxAttempts
150
+ }
151
+
152
+ if otherBlock .SleepIntervalSec > 0 {
153
+ existingBlock .SleepIntervalSec = otherBlock .SleepIntervalSec
154
+ }
155
+
156
+ continue
157
+ }
158
+
159
+ retryMap [otherBlock .Label ] = otherBlock
145
160
}
146
161
147
- return clone
162
+ return util . MapToSlice ( retryMap )
148
163
}
149
164
150
- // Clone creates a deep copy of IgnoreBlock
151
- func (i * IgnoreBlock ) Clone () * IgnoreBlock {
152
- if i == nil {
153
- return nil
154
- }
165
+ // Merges two slices of IgnoreBlock, prioritizing the second slice
166
+ func mergeIgnoreBlocks (existing , other []* IgnoreBlock ) []* IgnoreBlock {
167
+ ignoreMap := make (map [string ]* IgnoreBlock , len (existing )+ len (other ))
155
168
156
- clone := & IgnoreBlock {
157
- Label : i . Label ,
158
- Message : i . Message ,
169
+ // Add existing ignore blocks
170
+ for _ , block := range existing {
171
+ ignoreMap [ block . Label ] = block
159
172
}
160
173
161
- // Deep copy IgnorableErrors slice
162
- if i .IgnorableErrors != nil {
163
- clone .IgnorableErrors = make ([]string , len (i .IgnorableErrors ))
164
- copy (clone .IgnorableErrors , i .IgnorableErrors )
165
- }
174
+ // Merge ignore blocks from 'other'
175
+ for _ , otherBlock := range other {
176
+ if existingBlock , found := ignoreMap [otherBlock .Label ]; found {
177
+ existingBlock .IgnorableErrors = util .MergeStringSlices (existingBlock .IgnorableErrors , otherBlock .IgnorableErrors )
166
178
167
- // Deep copy Signals map
168
- if i .Signals != nil {
169
- clone .Signals = make (map [string ]cty.Value , len (i .Signals ))
170
- maps .Copy (clone .Signals , i .Signals )
179
+ if otherBlock .Message != "" {
180
+ existingBlock .Message = otherBlock .Message
181
+ }
182
+
183
+ if otherBlock .Signals != nil {
184
+ if existingBlock .Signals == nil {
185
+ existingBlock .Signals = make (map [string ]cty.Value , len (otherBlock .Signals ))
186
+ }
187
+
188
+ maps .Copy (existingBlock .Signals , otherBlock .Signals )
189
+ }
190
+ } else {
191
+ ignoreMap [otherBlock .Label ] = otherBlock
192
+ }
171
193
}
172
194
173
- return clone
195
+ // Convert map back to slice
196
+ return util .MapToSlice (ignoreMap )
174
197
}
0 commit comments