Skip to content

Commit

Permalink
Support local tag and boolean tag (#527)
Browse files Browse the repository at this point in the history
* support local tag and boolean tag

* add test case
  • Loading branch information
goccy authored Nov 12, 2024
1 parent a2d04d6 commit cb4e1b0
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 33 deletions.
20 changes: 20 additions & 0 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"reflect"
"sort"
"strconv"
"strings"
"time"

"github.com/goccy/go-yaml/ast"
Expand Down Expand Up @@ -332,10 +333,29 @@ func (d *Decoder) nodeToValue(node ast.Node) (any, error) {
}
b, _ := base64.StdEncoding.DecodeString(v.(string))
return b, nil
case token.BooleanTag:
v, err := d.nodeToValue(n.Value)
if err != nil {
return nil, err
}
str := strings.ToLower(fmt.Sprint(v))
b, err := strconv.ParseBool(str)
if err == nil {
return b, nil
}
switch str {
case "yes":
return true, nil
case "no":
return false, nil
}
return nil, errors.ErrSyntax(fmt.Sprintf("cannot convert %q to boolean", fmt.Sprint(v)), n.Value.GetToken())
case token.StringTag:
return d.nodeToValue(n.Value)
case token.MappingTag:
return d.nodeToValue(n.Value)
default:
return d.nodeToValue(n.Value)
}
case *ast.AnchorNode:
anchorName := n.Name.GetToken().Value
Expand Down
8 changes: 8 additions & 0 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,14 @@ func TestDecoder(t *testing.T) {
"v: !!timestamp 2015-01-01",
map[string]time.Time{"v": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
},
{
"v: !!bool yes",
map[string]bool{"v": true},
},
{
"v: !!bool False",
map[string]bool{"v": false},
},

// Flow sequence
{
Expand Down
7 changes: 6 additions & 1 deletion parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) {
token.StringTag,
token.BinaryTag,
token.TimestampTag,
token.BooleanTag,
token.NullTag:
typ := p.currentToken().Type
if typ == token.LiteralType || typ == token.FoldedType {
Expand All @@ -252,7 +253,11 @@ func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) {
token.SetTag:
err = errors.ErrSyntax(fmt.Sprintf("sorry, currently not supported %s tag", tagToken.Value), tagToken)
default:
err = errors.ErrSyntax(fmt.Sprintf("unknown tag name %q specified", tagToken.Value), tagToken)
if strings.HasPrefix(tagToken.Value, "!!") {
err = errors.ErrSyntax(fmt.Sprintf("unknown secondary tag name %q specified", tagToken.Value), tagToken)
} else {
value, err = p.parseToken(ctx, p.currentToken())
}
}
if err != nil {
return nil, err
Expand Down
49 changes: 17 additions & 32 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,20 @@ func TestParser(t *testing.T) {
a: {
b: c
}}
`,
`
- !tag
a: b
c: d
`,
`
a: !tag
b: c
`,
`
a: !tag
b: c
d: e
`,
}
for _, src := range sources {
Expand Down Expand Up @@ -958,41 +972,12 @@ func TestSyntaxError(t *testing.T) {
expect string
}{
{
`v: !!int64 2`,
`
- !tag
a: b
c: d
`,
`
[2:3] unknown tag name "!tag" specified
> 2 | - !tag
^
3 | a: b
4 | c: d`,
},
{
`
a: !tag
b: c
`,
`
[2:4] unknown tag name "!tag" specified
> 2 | a: !tag
[1:4] unknown secondary tag name "!!int64" specified
> 1 | v: !!int64 2
^
3 | b: c`,
},
{
`
a: !tag
b: c
d: e
`,
`
[2:4] unknown tag name "!tag" specified
> 2 | a: !tag
^
3 | b: c
4 | d: e`,
},
{
`
Expand Down
12 changes: 12 additions & 0 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,8 @@ const (
SetTag ReservedTagKeyword = "!!set"
// TimestampTag `!!timestamp` tag
TimestampTag ReservedTagKeyword = "!!timestamp"
// BooleanTag `!!bool` tag
BooleanTag ReservedTagKeyword = "!!bool"
)

var (
Expand Down Expand Up @@ -506,6 +508,16 @@ var (
Position: pos,
}
},
BooleanTag: func(value, org string, pos *Position) *Token {
return &Token{
Type: TagType,
CharacterType: CharacterTypeIndicator,
Indicator: NodePropertyIndicator,
Value: value,
Origin: org,
Position: pos,
}
},
}
)

Expand Down

0 comments on commit cb4e1b0

Please sign in to comment.