package hcl import ( "errors" "fmt" "reflect" "strings" ) const ( ElementTypeAttribute ElementType = "attr" ElementTypeBlock ElementType = "block" ElementTypeLabel ElementType = "label" ElementTypeRemain ElementType = "remain" ) var ErrNoHclTag = errors.New("no hcl tag") type ElementType string type FieldMeta struct { Name string Type ElementType Optional bool Ignore bool } func ExtractFieldMeta(t reflect.StructField, readTagName, writeTagName string) (FieldMeta, error) { hclTag, present := t.Tag.Lookup(readTagName) if !present { return FieldMeta{}, ErrNoHclTag } cfg := FieldMeta{ Name: t.Name, Type: ElementTypeAttribute, } if hclWriteTag, present := t.Tag.Lookup(writeTagName); present && hclWriteTag == "-" { cfg.Ignore = true return cfg, nil } split := strings.Split(hclTag, ",") if len(split) > 0 && split[0] != "" { cfg.Name = split[0] } if len(split) > 1 { switch split[1] { case "": fallthrough case "attr": cfg.Type = ElementTypeAttribute case "optional": cfg.Optional = true case "label": cfg.Type = ElementTypeLabel case "block": cfg.Type = ElementTypeBlock case "remain": cfg.Type = ElementTypeRemain default: return FieldMeta{}, fmt.Errorf("unknown element type %q", split[1]) } } return cfg, nil }