Skip to content

Commit 57ecfbd

Browse files
committed
Support twiddling field names in anonymous markers
This supports changing field names in anonymous markers, meaning you can have a marker like ``` //+default=<any> ``` map to a struct ``` type Default struct { Value interface{} } ``` by changing the definition up a bit. This supports when you need to make an any-type definition and also implement methods on it, like for defaulting.
1 parent aef99b2 commit 57ecfbd

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

pkg/markers/parse.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,9 +768,21 @@ func (d *Definition) Parse(rawMarker string) (interface{}, error) {
768768
// TODO(directxman12): strict parsing where we error out if certain fields aren't optional
769769
seen := make(map[string]struct{}, len(d.Fields))
770770
if d.AnonymousField() && scanner.Peek() != sc.EOF {
771+
// might still be a struct that something fiddled with, so double check
772+
structFieldName := d.FieldNames[""]
773+
outTarget := out
774+
if structFieldName != "" {
775+
// it's a struct field mapped to an anonymous marker
776+
outTarget = out.FieldByName(structFieldName)
777+
if !outTarget.CanSet() {
778+
scanner.Error(scanner, fmt.Sprintf("cannot set field %q (might not exist)", structFieldName))
779+
return out.Interface(), loader.MaybeErrList(errs)
780+
}
781+
}
782+
771783
// no need for trying to parse field names if we're not a struct
772784
field := d.Fields[""]
773-
field.Parse(scanner, fields, out)
785+
field.Parse(scanner, fields, outTarget)
774786
seen[""] = struct{}{} // mark as seen for strict definitions
775787
} else if !d.Empty() && scanner.Peek() != sc.EOF {
776788
// if we expect *and* actually have arguments passed

pkg/markers/parse_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ type allOptionalStruct struct {
5151
OptInt *int
5252
}
5353

54+
type CustomType struct {
55+
Value interface{}
56+
}
57+
5458
var _ = Describe("Parsing", func() {
5559
var reg *Registry
5660

@@ -71,8 +75,17 @@ var _ = Describe("Parsing", func() {
7175
mustDefine(reg, "testing:tripleDefined", DescribesPackage, 0)
7276
mustDefine(reg, "testing:tripleDefined", DescribesField, "")
7377
mustDefine(reg, "testing:tripleDefined", DescribesType, false)
78+
79+
defn, err := MakeDefinition("testing:custom", DescribesPackage, CustomType{})
80+
Expect(err).NotTo(HaveOccurred())
81+
defn.FieldNames = map[string]string{"": "Value"}
82+
defn.Fields = map[string]Argument{"": defn.Fields["value"]}
83+
84+
Expect(reg.Register(defn)).To(Succeed())
7485
})
7586

87+
It("should work with fiddled field names", parseTestCase{reg: &reg, raw: "+testing:custom={hi}", output: CustomType{Value: []string{"hi"}}}.Run)
88+
7689
It("should parse name-only markers", parseTestCase{reg: &reg, raw: "+testing:empty", output: struct{}{}}.Run)
7790

7891
Context("when parsing anonymous markers", func() {

0 commit comments

Comments
 (0)