Skip to content

Commit eff4f35

Browse files
committed
fix bugs - improve task code and add task example code
1 parent 182602c commit eff4f35

11 files changed

Lines changed: 197 additions & 237 deletions

dstruct.generated.struct.go

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func NewGeneratedStructWithConfig[T any](val T,
5454
}
5555

5656
for _, v := range customTypes {
57-
generatedStruct.addCustomType(v)
57+
generatedStruct.AddCustomType(v)
5858
}
5959
generatedStruct.addCustomTypes()
6060
generatedStruct.populateGeneratedFields(generatedStruct.root)
@@ -266,24 +266,18 @@ func (gs *DStructGeneratedStruct[T]) SetGenerationFunctions(
266266
gs.propagateGenerationFunctions(gs.root, functions)
267267
}
268268

269-
// SetFieldFromTask implements GeneratedStruct.SetFieldFromTask
270-
func (gs *DStructGeneratedStruct[T]) SetFieldFromTask(
269+
// SetFieldFromTaskInstance implements GeneratedStruct.SetFieldFromTaskInstanc
270+
func (gs *DStructGeneratedStruct[T]) SetFieldFromTaskInstance(
271271
field string,
272-
task generator.Task,
273-
params ...any,
272+
taskInstance generator.TaskInstance,
274273
) error {
275-
taskProperties, err := generator.CreateTaskProperties(
276-
field,
277-
generator.GetTagForTask(generator.TaskName(task.Name()), params...),
278-
)
279-
if err != nil {
280-
return err
281-
}
282-
283274
gs.SetFieldGenerationFunction(
284275
field,
285-
core.NewFunctionHolderNoArgs(task.GenerationFunction(*taskProperties)),
276+
core.NewFunctionHolderNoArgs(
277+
taskInstance.GenerationFunction(),
278+
),
286279
)
280+
287281
return nil
288282
}
289283

@@ -334,15 +328,15 @@ func (gs *DStructGeneratedStruct[T]) generateFields() {
334328
}
335329

336330
func (gs *DStructGeneratedStruct[T]) addCustomTypes() {
337-
gs.addCustomType(
331+
gs.AddCustomType(
338332
CustomType{
339333
time.Time{},
340334
core.DefaultDateFunctionHolder(gs.structConfig.GenerationConfig.Date()),
341335
},
342336
)
343337
}
344338

345-
func (gs *DStructGeneratedStruct[T]) addCustomType(customType CustomType) {
339+
func (gs *DStructGeneratedStruct[T]) AddCustomType(customType CustomType) {
346340
// TODO: restrict some types from being added such as nil, ints etc
347341
gs.customTypes[reflect.TypeOf(customType.Value).String()] = customType.FunctionHolder
348342
// the function holder kind is the find that the function retrusn which could either be an existing kind or a new kind i.ie time.Time would be a new kind
@@ -368,23 +362,6 @@ func (gs *DStructGeneratedStruct[T]) populateGeneratedFields(node *Node[StructFi
368362
if gs.fieldContexts[field.data.qualifiedName] != nil {
369363
continue
370364
}
371-
// fmt.Println(
372-
// "Field: ",
373-
// field.data.qualifiedName,
374-
// field.data.value.Kind(),
375-
// field.data.ptrDepth,
376-
// field.data.ptrKind,
377-
// field.data.IsFieldDereferencable(),
378-
// )
379-
380-
// fmt.Println(
381-
// "POP: ",
382-
// field.data.qualifiedName,
383-
// gs.customTypes,
384-
// field.data.goType,
385-
// field.data.dstructType,
386-
387-
// )
388365

389366
if customType := gs.customTypes[field.data.goType]; customType != nil {
390367
gs.fieldContexts[field.data.qualifiedName] = core.NewGeneratedFieldContext(

examples/task/main.go

Lines changed: 49 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -12,83 +12,77 @@ import (
1212
)
1313

1414
const (
15-
GenInt32 generator.TaskName = "GenInt32"
15+
GenInt32 string = "GenInt32"
1616
)
1717

1818
type genInt32Params struct {
1919
min int32
2020
max int32
2121
}
2222

23-
type GenInt32Task struct{}
24-
25-
// Ensure GenInt32Task implements Task.
26-
var _ generator.Task = &GenInt32Task{}
23+
type GenInt32Task struct {
24+
generator.BaseTask
25+
numberConfig config.NumberRangeConfig
26+
}
2727

28-
// Tags implements Task.
29-
func (g *GenInt32Task) Name() string {
30-
return string(GenInt32)
28+
type GenInt32TaskInstance struct {
29+
GenInt32Task
30+
genFunc generator.GenerationFunction
3131
}
3232

33-
// GenerationFunction implements Task.
34-
func (g *GenInt32Task) GenerationFunction(
35-
taskProperties generator.TaskProperties,
36-
) generator.GenerationFunction {
37-
generator.ValidateParamCount(g, taskProperties)
38-
params := g.getInt32Params(taskProperties.FieldName, taskProperties.Parameters)
39-
numberConfig := config.NewNumberRangeConfig()
40-
numberConfig.Int().SetRange(int(params.min), int(params.max))
41-
return core.GenerateNumberFunc[int](numberConfig)
33+
var (
34+
_ generator.TaskInstance = &GenInt32TaskInstance{}
35+
// Ensure GenInt32Task implements Task.
36+
_ generator.Task = &GenInt32Task{}
37+
)
38+
39+
func NewGenInt32Task() *GenInt32Task {
40+
gt := &GenInt32Task{
41+
numberConfig: config.NewNumberRangeConfig(),
42+
BaseTask: *generator.NewBaseTask(string(GenInt32), 2),
43+
}
44+
return gt
4245
}
4346

44-
func (g *GenInt32Task) ExpectedParameterCount() int {
45-
return 2
47+
func (g GenInt32Task) Instance(params ...string) generator.TaskInstance {
48+
gt := &GenInt32TaskInstance{
49+
GenInt32Task: g,
50+
}
51+
gt.numberConfig = g.numberConfig.Copy()
52+
gt.SetParameters(params...)
53+
gt.genFunc = core.GenerateNumberFunc[int32](gt.numberConfig)
54+
return gt
4655
}
4756

48-
func (g *GenInt32Task) FunctionHolder(taskProperties generator.TaskProperties) core.FunctionHolder {
49-
return core.NewFunctionHolderNoArgs(g.GenerationFunction(taskProperties))
57+
func (g *GenInt32TaskInstance) GenerationFunction() generator.GenerationFunction {
58+
return g.genFunc
5059
}
5160

52-
func (g *GenInt32Task) getInt32Params(fieldName string, params []string) genInt32Params {
53-
param_1, err := strconv.Atoi(params[0])
61+
func (g *GenInt32TaskInstance) SetParameters(params ...string) {
62+
g.ValidateParamCount(params...)
63+
min, err := strconv.Atoi(params[0])
5464
if err != nil {
55-
panic(fmt.Sprintf("error with field %s: task %s error: %s", fieldName, GenInt32, err))
65+
panic(fmt.Sprintf("Error parsing min value: %s", err))
5666
}
57-
58-
param_2, err := strconv.Atoi(params[1])
67+
max, err := strconv.Atoi(params[1])
5968
if err != nil {
60-
panic(fmt.Sprintf("error with field %s: task %s error: %s", fieldName, GenInt32, err))
61-
}
62-
63-
if param_1 > param_2 {
64-
err = fmt.Errorf(
65-
"min must be less or equal to the max value min = %d max = %d",
66-
param_1,
67-
param_2,
68-
)
69-
panic(fmt.Sprintf("error with field %s: task %s error: %s", fieldName, GenInt32, err))
70-
69+
panic(fmt.Sprintf("Error parsing max value: %s", err))
7170
}
7271

73-
return genInt32Params{
74-
min: int32(param_1),
75-
max: int32(param_2),
72+
if min > max {
73+
panic(fmt.Sprintf("min value %d is greater than max value %d", min, max))
7674
}
75+
g.numberConfig.Int32().SetRange(int32(min), int32(max))
7776
}
7877

7978
type M struct {
8079
Name string
8180
}
8281

8382
type Person struct {
84-
// Love ABC
8583
Age *int
8684
Time time.Time
8785
Other *M
88-
89-
// Parray []Person
90-
91-
// Person *Person
9286
}
9387

9488
type P struct {
@@ -97,72 +91,20 @@ type P struct {
9791
}
9892

9993
type Test struct {
100-
// A *int
101-
// S string
102-
C int
103-
Person P `json:"person"`
104-
94+
B int32 `gen_task:"GenInt32(2)" gen_task_1:"10" gen_task_2:"20"`
95+
C int32
96+
Person P
10597
Cpoint *int
10698
T time.Time
107-
108-
// Pa []Pa
109-
// Parray []Person
110-
111-
// L
11299
}
113100

114101
func main() {
115-
// e := dstruct.ExtendStruct(Test{}).Build().Instance()
116-
// createTime := time.Now()
117-
// // for i := 0; i < 1; i++ {
118-
// // estruct.AddField(fmt.Sprintf("Test_%d", i), Test{}, "")
119-
// // }
120-
// fmt.Println(time.Since(createTime))
121-
// // b := estruct.Build()
122-
// //
123-
// st := config.GenerationSettings{SetNonRequiredFields: true}
124-
// gestruct := dstruct.NewGeneratedStructWithConfig(e,
125-
// config.NewDstructConfig(),
126-
// st,
127-
// )
128-
//
129-
// c := gestruct.GetGenerationConfig()
130-
// c.SetIntRange(20, 50)
131-
// st.SetNonRequiredFields = false
132-
//
133-
// // gestruct.SetFieldGenerationSettings("Person", st)
134-
// // gestruct.SetFieldGenerationConfig("Person", c)
135-
//
136-
// gTime := time.Now()
137-
// gestruct.Generate()
138-
// // gestruct.Update()
139-
// // gestruct.Set("Person.P", Person{Age: new(int), Time: time.Now()})
140-
// err := gestruct.Set(
141-
// "Person.P",
142-
// Person{Age: new(int), Time: time.Now(), Other: &M{Name: "Martin"}},
143-
// )
144-
// if err != nil {
145-
// // panic(err)
146-
// }
147-
//
148-
// fmt.Println("Time to generate: ", time.Since(gTime))
149-
// fmt.Printf("%+v\n", gestruct.Get_("Person.P.Other.Name"))
150-
// for field := range gestruct.GetFields() {
151-
// fmt.Println("Field: ", field)
152-
// fmt.Printf(
153-
// "'%s': dstruct: %+v goType: %+v\n",
154-
// field,
155-
// value.GetDstructType(),
156-
// value.GetGoType(),
157-
// )
158-
// }
159-
160102
generatedStuct := dstruct.NewGeneratedStructWithConfig(
161103
Test{Cpoint: new(int)},
162104
config.NewDstructConfig().SetSliceLength(3, 3),
163105
config.DefaultGenerationSettings(),
164106
)
165-
gt := &GenInt32Task{}
107+
gt := NewGenInt32Task()
166108
generator.AddTask(gt)
167109
if err := generatedStuct.Set("Person.P", Person{}); err != nil {
168110
panic(err)
@@ -171,12 +113,14 @@ func main() {
171113
"Person.Value",
172114
config.NewDstructConfig().SetIntRange(800, 1000),
173115
)
174-
175-
generatedStuct.SetFieldFromTask("C", gt, 300, 400)
176-
// generatedStuct.Update()
116+
gti := gt.Instance("20", "30").(*GenInt32TaskInstance)
117+
generatedStuct.SetFieldFromTaskInstance("C", gti)
177118
generatedStuct.Generate()
178119

179120
fmt.Printf("%+v\n", generatedStuct)
121+
gti.SetParameters("100", "200")
180122

181-
fmt.Println("Testing task")
123+
generatedStuct.Generate()
124+
125+
fmt.Printf("%+v\n", generatedStuct)
182126
}

generated.struct.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ type GeneratedStruct interface {
7272
// SetGenerationFunctions sets the generation functions for the struct and propagates the settings to all fields
7373
SetGenerationFunctions(functions core.DefaultGenerationFunctions)
7474

75-
// SetFieldFromTask sets the field value from the task. The task is used to generate the value for the field.
76-
SetFieldFromTask(field string, task generator.Task, params ...any) error
75+
// SetFieldFromTaskInstance sets the field value from the task instance. The task is used to generate the value for the field.
76+
SetFieldFromTaskInstance(
77+
field string,
78+
taskInstance generator.TaskInstance,
79+
) error
80+
81+
// AddCustomType adds a custom type to the struct. The custom type is used to generate values for fields of the custom type.
82+
AddCustomType(customType CustomType)
7783
}

generator/base.task.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package generator
2+
3+
import (
4+
"fmt"
5+
"reflect"
6+
)
7+
8+
type BaseTask struct {
9+
taskName string
10+
parameterCount int
11+
}
12+
13+
func NewBaseTask(taskName string, parameterCount int) *BaseTask {
14+
return &BaseTask{
15+
taskName: taskName,
16+
parameterCount: parameterCount,
17+
}
18+
}
19+
20+
func (b *BaseTask) ParameterCount() int {
21+
return b.parameterCount
22+
}
23+
24+
func (b *BaseTask) GetTags(params ...string) reflect.StructTag {
25+
b.ValidateParamCount(params...)
26+
tags := fmt.Sprintf(`gen_task:"%s(%d)"`, b.taskName, len(params))
27+
for i, p := range params {
28+
tags += fmt.Sprintf(` gen_task_%d:"%v"`, (i + 1), p)
29+
}
30+
return reflect.StructTag(tags)
31+
}
32+
33+
func (b *BaseTask) Name() string {
34+
return b.taskName
35+
}
36+
37+
func (b *BaseTask) ValidateParamCount(params ...string) {
38+
if len(params) != b.parameterCount && b.parameterCount != -1 {
39+
panic(
40+
fmt.Sprintf(
41+
"error with task '%s': task requires %d parameters but has %d",
42+
b.taskName,
43+
b.parameterCount,
44+
len(params),
45+
),
46+
)
47+
}
48+
}

generator/core/generated.field.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,15 +286,17 @@ func (field *GeneratedField) getGenerationFunction() generator.GenerationFunctio
286286

287287
_, ok = tags.Lookup("gen_task")
288288
if ok {
289-
taskProperties, err := generator.CreateTaskProperties(field.Name, tags)
289+
290+
taskProperties, err := generator.CreateTaskPropertiesFromTag(tags)
290291
if err != nil {
291-
panic(fmt.Sprintf("Error decoding gen_task: %s", err.Error()))
292+
panic(fmt.Sprintf("Error decoding gen_task for '%s': %s", field.Name, err.Error()))
292293
}
293294
task := generator.GetTask(taskProperties.TaskName)
294295
if task == nil {
295296
panic(fmt.Sprintf("Unregistered task %s", taskProperties.TaskName))
296297
}
297-
return task.GenerationFunction(*taskProperties)
298+
return task.Instance(taskProperties.Parameters()...).GenerationFunction()
299+
298300
}
299301

300302
// if we get no match, we default to the default generation function for the kind

generator/core/no.arg.function.holder.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ func NewFunctionHolderNoArgs(
1919
return &FunctionHolderWithNoArgs{
2020
BaseFunctionHolder: BaseFunctionHolder{
2121
generationFunction: generationFunction,
22+
resetFunction: func(cfg config.Config) generator.GenerationFunction {
23+
return generationFunction
24+
},
2225
},
2326
}
2427
}

0 commit comments

Comments
 (0)