diff --git a/README.md b/README.md index 25eebddf..d60ad03c 100644 --- a/README.md +++ b/README.md @@ -124,13 +124,21 @@ go test ./... ``` ## Roadmap ideas +### V1.0.x +- [x] Add visitor generation for unions +- [x] Add support for depth-first traversal +- [x] Add support for slice []{Variant} type traversal + ### V1.1.x -- [ ] Add support for map[any]{Variant} type +- [x] Add support for map[any]{Variant} type - [ ] Add breath-first reducer traversal -- [ ] Add leaf-first reducer traversal +- [ ] Add leaf-first reducer traversal [?] ### V1.2.x - [ ] Add support for not-stop able reducer ### V2.x.x -- [ ] Add support for generic union types \ No newline at end of file +- [ ] Add support for generic union types + +### Knows bugs +- [ ] Multiple go:generates mkunion in one file overwrite generated. Solution: split to multiple files diff --git a/example/where_predicate_example.go b/example/where_predicate_example.go index ed203ae9..9c0935ae 100644 --- a/example/where_predicate_example.go +++ b/example/where_predicate_example.go @@ -10,5 +10,6 @@ type ( Condition WherePredicate Then []WherePredicate X Eq + Y map[string]WherePredicate } ) diff --git a/infer_defaults.go b/infer_defaults.go index b052d590..4e0afa2f 100644 --- a/infer_defaults.go +++ b/infer_defaults.go @@ -50,12 +50,16 @@ func (f *InferredInfo) Visit(n ast.Node) ast.Visitor { } isList := false + isMap := false var id *ast.Ident var ok bool - if arr, isArr := field.Type.(*ast.ArrayType); isArr { + if arr, okArr := field.Type.(*ast.ArrayType); okArr { id, ok = arr.Elt.(*ast.Ident) isList = true + } else if m, okMap := field.Type.(*ast.MapType); okMap { + id, ok = m.Value.(*ast.Ident) + isMap = true } else { id, ok = field.Type.(*ast.Ident) } @@ -69,11 +73,13 @@ func (f *InferredInfo) Visit(n ast.Node) ast.Visitor { continue } - for _, n := range field.Names { + for _, ff := range field.Names { fieldTypeName := fieldName - branch := Branching{Lit: PtrStr(n.Name)} + branch := Branching{Lit: PtrStr(ff.Name)} if isList { - branch = Branching{List: PtrStr(n.Name)} + branch = Branching{List: PtrStr(ff.Name)} + } else if isMap { + branch = Branching{Map: PtrStr(ff.Name)} } f.Types[f.currentType][fieldTypeName] = append(f.Types[f.currentType][fieldTypeName], branch) } diff --git a/infer_defaults_test.go b/infer_defaults_test.go index efb0144c..d743ff31 100644 --- a/infer_defaults_test.go +++ b/infer_defaults_test.go @@ -33,6 +33,7 @@ func TestExtractInferenceForWherePredicate(t *testing.T) { "Path": { {Lit: PtrStr("Condition")}, {List: PtrStr("Then")}, + {Map: PtrStr("Y")}, }, }, out.ForVariantType("WherePredicate", []string{"Eq", "And", "Or", "Path"})) diff --git a/reducer_generator.go b/reducer_generator.go index 31efb476..595d66b8 100644 --- a/reducer_generator.go +++ b/reducer_generator.go @@ -15,6 +15,7 @@ type variantName = string type Branching struct { Lit *string List *string + Map *string } type ReducerGenerator struct { @@ -62,6 +63,12 @@ func (d *{{ $name }}DepthFirstVisitor[A]) Visit{{ . }}(v *{{ . }}) any { return nil } } + {{- else if .Map }} + for idx, _ := range v.{{ .Map }} { + if _ = v.{{ .Map }}[idx].Accept(d); d.stop { + return nil + } + } {{- end -}} {{- end }} diff --git a/reducer_generator_test.go b/reducer_generator_test.go index 9e348e63..a09242bb 100644 --- a/reducer_generator_test.go +++ b/reducer_generator_test.go @@ -11,7 +11,11 @@ func TestTravers(t *testing.T) { PackageName: "visitor", Types: []string{"Branch", "Leaf"}, Branches: map[string][]Branching{ - "Branch": {{Lit: PtrStr("L")}, {Lit: PtrStr("R")}}, + "Branch": { + {Lit: PtrStr("Lit")}, + {List: PtrStr("List")}, + {Map: PtrStr("Map")}, + }, }, } @@ -40,11 +44,18 @@ func (d *TreeDepthFirstVisitor[A]) VisitBranch(v *Branch) any { if d.stop { return nil } - if _ = v.L.Accept(d); d.stop { + if _ = v.Lit.Accept(d); d.stop { return nil } - if _ = v.R.Accept(d); d.stop { - return nil + for idx := range v.List { + if _ = v.List[idx].Accept(d); d.stop { + return nil + } + } + for idx, _ := range v.Map { + if _ = v.Map[idx].Accept(d); d.stop { + return nil + } } return nil