@@ -23,27 +23,49 @@ type StoreOptions struct {
2323 workers int
2424}
2525
26+ func (o * StoreOptions ) Default () * StoreOptions {
27+ o .clearOnExecution = false
28+ o .stopOnFirstError = false
29+ o .sequential = false
30+ o .reverse = false
31+ o .joinErrors = false
32+ o .onlyOnce = false
33+ o .workers = 0
34+ return o
35+ }
36+
2637func (o * StoreOptions ) Merge (opts * StoreOptions ) * StoreOptions {
2738 if opts == nil {
2839 return o
2940 }
30- return & StoreOptions {
31- clearOnExecution : opts .clearOnExecution || o .clearOnExecution ,
32- stopOnFirstError : opts .stopOnFirstError || o .stopOnFirstError ,
33- sequential : opts .sequential || o .sequential ,
34- reverse : opts .reverse || o .reverse ,
35- joinErrors : opts .joinErrors || o .joinErrors ,
36- onlyOnce : opts .onlyOnce || o .onlyOnce ,
37- workers : safecast .ToInt (math .Max (float64 (opts .workers ), float64 (o .workers ))),
38- }
41+ o .clearOnExecution = opts .clearOnExecution || o .clearOnExecution
42+ o .stopOnFirstError = opts .stopOnFirstError || o .stopOnFirstError
43+ o .sequential = opts .sequential || o .sequential
44+ o .reverse = opts .reverse || o .reverse
45+ o .joinErrors = opts .joinErrors || o .joinErrors
46+ o .onlyOnce = opts .onlyOnce || o .onlyOnce
47+ o .workers = safecast .ToInt (math .Max (float64 (opts .workers ), float64 (o .workers )))
48+ return o
49+ }
50+
51+ func (o * StoreOptions ) MergeWithOptions (opt ... StoreOption ) * StoreOptions {
52+ return o .Merge (WithOptions (opt ... ))
53+ }
54+
55+ func (o * StoreOptions ) Overwrite (opts * StoreOptions ) * StoreOptions {
56+ return o .Default ().Merge (opts )
57+ }
58+
59+ func (o * StoreOptions ) WithOptions (opts ... StoreOption ) * StoreOptions {
60+ return o .Overwrite (WithOptions (opts ... ))
3961}
4062
4163func (o * StoreOptions ) Options () []StoreOption {
4264 return []StoreOption {
4365 func (opts * StoreOptions ) * StoreOptions {
4466 op := o
4567 if op == nil {
46- op = & StoreOptions {}
68+ op = DefaultOptions ()
4769 }
4870 return op .Merge (opts )
4971 },
@@ -55,7 +77,7 @@ type StoreOption func(*StoreOptions) *StoreOptions
5577// StopOnFirstError stops ExecutionGroup execution on first error.
5678var StopOnFirstError StoreOption = func (o * StoreOptions ) * StoreOptions {
5779 if o == nil {
58- o = & StoreOptions {}
80+ o = DefaultOptions ()
5981 }
6082 o .stopOnFirstError = true
6183 o .joinErrors = false
@@ -66,7 +88,7 @@ var StopOnFirstError StoreOption = func(o *StoreOptions) *StoreOptions {
6688// This option should not be used in combination to StopOnFirstError.
6789var JoinErrors StoreOption = func (o * StoreOptions ) * StoreOptions {
6890 if o == nil {
69- o = & StoreOptions {}
91+ o = DefaultOptions ()
7092 }
7193 o .stopOnFirstError = false
7294 o .joinErrors = true
@@ -76,7 +98,7 @@ var JoinErrors StoreOption = func(o *StoreOptions) *StoreOptions {
7698// OnlyOnce will ensure the function are executed only once if they do.
7799var OnlyOnce StoreOption = func (o * StoreOptions ) * StoreOptions {
78100 if o == nil {
79- o = & StoreOptions {}
101+ o = DefaultOptions ()
80102 }
81103 o .onlyOnce = true
82104 return o
@@ -85,7 +107,7 @@ var OnlyOnce StoreOption = func(o *StoreOptions) *StoreOptions {
85107// AnyTimes will allow the functions to be executed as often that they might be.
86108var AnyTimes StoreOption = func (o * StoreOptions ) * StoreOptions {
87109 if o == nil {
88- o = & StoreOptions {}
110+ o = DefaultOptions ()
89111 }
90112 o .onlyOnce = false
91113 return o
@@ -94,7 +116,7 @@ var AnyTimes StoreOption = func(o *StoreOptions) *StoreOptions {
94116// ExecuteAll executes all functions in the ExecutionGroup even if an error is raised. the first error raised is then returned.
95117var ExecuteAll StoreOption = func (o * StoreOptions ) * StoreOptions {
96118 if o == nil {
97- o = & StoreOptions {}
119+ o = DefaultOptions ()
98120 }
99121 o .stopOnFirstError = false
100122 return o
@@ -103,7 +125,7 @@ var ExecuteAll StoreOption = func(o *StoreOptions) *StoreOptions {
103125// ClearAfterExecution clears the ExecutionGroup after execution.
104126var ClearAfterExecution StoreOption = func (o * StoreOptions ) * StoreOptions {
105127 if o == nil {
106- o = & StoreOptions {}
128+ o = DefaultOptions ()
107129 }
108130 o .clearOnExecution = true
109131 return o
@@ -112,7 +134,7 @@ var ClearAfterExecution StoreOption = func(o *StoreOptions) *StoreOptions {
112134// RetainAfterExecution keep the ExecutionGroup intact after execution (no reset).
113135var RetainAfterExecution StoreOption = func (o * StoreOptions ) * StoreOptions {
114136 if o == nil {
115- o = & StoreOptions {}
137+ o = DefaultOptions ()
116138 }
117139 o .clearOnExecution = false
118140 return o
@@ -121,7 +143,7 @@ var RetainAfterExecution StoreOption = func(o *StoreOptions) *StoreOptions {
121143// Parallel ensures every function registered in the ExecutionGroup is executed concurrently in the order they were registered.
122144var Parallel StoreOption = func (o * StoreOptions ) * StoreOptions {
123145 if o == nil {
124- o = & StoreOptions {}
146+ o = DefaultOptions ()
125147 }
126148 o .sequential = false
127149 return o
@@ -131,7 +153,7 @@ var Parallel StoreOption = func(o *StoreOptions) *StoreOptions {
131153func Workers (workers int ) StoreOption {
132154 return func (o * StoreOptions ) * StoreOptions {
133155 if o == nil {
134- o = & StoreOptions {}
156+ o = DefaultOptions ()
135157 }
136158 o .workers = workers
137159 o .sequential = false
@@ -142,7 +164,7 @@ func Workers(workers int) StoreOption {
142164// Sequential ensures every function registered in the ExecutionGroup is executed sequentially in the order they were registered.
143165var Sequential StoreOption = func (o * StoreOptions ) * StoreOptions {
144166 if o == nil {
145- o = & StoreOptions {}
167+ o = DefaultOptions ()
146168 }
147169 o .sequential = true
148170 return o
@@ -151,7 +173,7 @@ var Sequential StoreOption = func(o *StoreOptions) *StoreOptions {
151173// SequentialInReverse ensures every function registered in the ExecutionGroup is executed sequentially but in the reverse order they were registered.
152174var SequentialInReverse StoreOption = func (o * StoreOptions ) * StoreOptions {
153175 if o == nil {
154- o = & StoreOptions {}
176+ o = DefaultOptions ()
155177 }
156178 o .sequential = true
157179 o .reverse = true
@@ -164,11 +186,34 @@ func WithOptions(option ...StoreOption) (opts *StoreOptions) {
164186 opts = option [i ](opts )
165187 }
166188 if opts == nil {
167- opts = & StoreOptions {}
189+ opts = DefaultOptions ()
168190 }
169191 return
170192}
171193
194+ // DefaultOptions returns the default store configuration
195+ func DefaultOptions () * StoreOptions {
196+ opts := & StoreOptions {}
197+ return opts .Default ()
198+ }
199+
200+ type IExecutor interface {
201+ // Execute executes all the functions in the group.
202+ Execute (ctx context.Context ) error
203+ }
204+
205+ type IExecutionGroup [T any ] interface {
206+ IExecutor
207+ RegisterFunction (function ... T )
208+ Len () int
209+ }
210+
211+ type ICompoundExecutionGroup [T any ] interface {
212+ IExecutionGroup [T ]
213+ // RegisterExecutor registers executors of any kind to the group: they could be functions or sub-groups.
214+ RegisterExecutor (executor ... IExecutor )
215+ }
216+
172217// NewExecutionGroup returns an execution group which executes functions according to store options.
173218func NewExecutionGroup [T any ](executeFunc ExecuteFunc [T ], options ... StoreOption ) * ExecutionGroup [T ] {
174219
@@ -366,3 +411,25 @@ func newWrapped[T any](e T, once bool) wrappedElement[T] {
366411 return newBasicWrap [T ](e )
367412 }
368413}
414+
415+ var _ ICompoundExecutionGroup [ContextualFunc ] = & CompoundExecutionGroup {}
416+
417+ // NewCompoundExecutionGroup returns an execution group made of executors
418+ func NewCompoundExecutionGroup (options ... StoreOption ) * CompoundExecutionGroup {
419+ return & CompoundExecutionGroup {
420+ ContextualFunctionGroup : * NewContextualGroup (options ... ),
421+ }
422+ }
423+
424+ type CompoundExecutionGroup struct {
425+ ContextualFunctionGroup
426+ }
427+
428+ // RegisterExecutor registers executors
429+ func (g * CompoundExecutionGroup ) RegisterExecutor (group ... IExecutor ) {
430+ for i := range group {
431+ g .RegisterFunction (func (ctx context.Context ) error {
432+ return group [i ].Execute (ctx )
433+ })
434+ }
435+ }
0 commit comments