updated vendor
This commit is contained in:
+132
-26
@@ -28,13 +28,17 @@ const (
|
||||
mergeTag = "!!merge"
|
||||
)
|
||||
|
||||
// longTagPrefix is the standard YAML tag prefix for core types.
|
||||
const longTagPrefix = "tag:yaml.org,2002:"
|
||||
|
||||
// longTags maps short tags to their long form representations.
|
||||
// shortTags maps long tags to their short form representations.
|
||||
var (
|
||||
longTags = make(map[string]string)
|
||||
shortTags = make(map[string]string)
|
||||
)
|
||||
|
||||
// init initializes the tag conversion maps.
|
||||
func init() {
|
||||
for _, stag := range []string{nullTag, boolTag, strTag, intTag, floatTag, timestampTag, seqTag, mapTag, binaryTag, mergeTag} {
|
||||
ltag := longTag(stag)
|
||||
@@ -43,6 +47,7 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// shortTag converts a long-form tag to its short form (e.g., "tag:yaml.org,2002:str" to "!!str").
|
||||
func shortTag(tag string) string {
|
||||
if strings.HasPrefix(tag, longTagPrefix) {
|
||||
if stag, ok := shortTags[tag]; ok {
|
||||
@@ -53,6 +58,7 @@ func shortTag(tag string) string {
|
||||
return tag
|
||||
}
|
||||
|
||||
// longTag converts a short-form tag to its long form (e.g., "!!str" to "tag:yaml.org,2002:str").
|
||||
func longTag(tag string) string {
|
||||
if strings.HasPrefix(tag, "!!") {
|
||||
if ltag, ok := longTags[tag]; ok {
|
||||
@@ -66,6 +72,7 @@ func longTag(tag string) string {
|
||||
// Kind represents the type of YAML node
|
||||
type Kind uint32
|
||||
|
||||
// Kind constants define the different types of YAML nodes.
|
||||
const (
|
||||
DocumentNode Kind = 1 << iota
|
||||
SequenceNode
|
||||
@@ -78,6 +85,7 @@ const (
|
||||
// Style represents the formatting style of a YAML node
|
||||
type Style uint32
|
||||
|
||||
// Style constants define different formatting styles for YAML nodes.
|
||||
const (
|
||||
TaggedStyle Style = 1 << iota
|
||||
DoubleQuotedStyle
|
||||
@@ -99,6 +107,14 @@ type StreamTagDirective struct {
|
||||
Prefix string
|
||||
}
|
||||
|
||||
// Stream holds stream-level metadata for StreamNode.
|
||||
// This includes encoding, version directive, and tag directives.
|
||||
type Stream struct {
|
||||
Encoding Encoding
|
||||
Version *StreamVersionDirective
|
||||
TagDirectives []StreamTagDirective
|
||||
}
|
||||
|
||||
// Node represents an element in the YAML document hierarchy. While documents
|
||||
// are typically encoded and decoded into higher level types, such as structs
|
||||
// and maps, Node is an intermediate representation that allows detailed
|
||||
@@ -171,26 +187,15 @@ type Node struct {
|
||||
Line int
|
||||
Column int
|
||||
|
||||
// StreamNode-specific fields (only valid when Kind == StreamNode)
|
||||
|
||||
// Encoding holds the stream encoding (UTF-8, UTF-16LE, UTF-16BE).
|
||||
// Only valid for StreamNode.
|
||||
Encoding Encoding
|
||||
|
||||
// Version holds the YAML version directive (%YAML).
|
||||
// Only valid for StreamNode.
|
||||
Version *StreamVersionDirective
|
||||
|
||||
// TagDirectives holds the %TAG directives.
|
||||
// Only valid for StreamNode.
|
||||
TagDirectives []StreamTagDirective
|
||||
// Stream holds stream metadata (non-nil only when Kind == StreamNode).
|
||||
Stream *Stream
|
||||
}
|
||||
|
||||
// IsZero returns whether the node has all of its fields unset.
|
||||
func (n *Node) IsZero() bool {
|
||||
return n.Kind == 0 && n.Style == 0 && n.Tag == "" && n.Value == "" && n.Anchor == "" && n.Alias == nil && n.Content == nil &&
|
||||
n.HeadComment == "" && n.LineComment == "" && n.FootComment == "" && n.Line == 0 && n.Column == 0 &&
|
||||
n.Encoding == 0 && n.Version == nil && n.TagDirectives == nil
|
||||
n.Stream == nil
|
||||
}
|
||||
|
||||
// LongTag returns the long form of the tag that indicates the data type for
|
||||
@@ -230,6 +235,7 @@ func (n *Node) ShortTag() string {
|
||||
return shortTag(n.Tag)
|
||||
}
|
||||
|
||||
// indicatedString returns true if the node's style explicitly indicates a string type.
|
||||
func (n *Node) indicatedString() bool {
|
||||
return n.Kind == ScalarNode &&
|
||||
(shortTag(n.Tag) == strTag ||
|
||||
@@ -324,14 +330,22 @@ func (n *Node) Load(v any, opts ...Option) (err error) {
|
||||
// conversion of Go values into YAML.
|
||||
func (n *Node) Encode(v any) (err error) {
|
||||
defer handleErr(&err)
|
||||
e := NewRepresenter(noWriter, DefaultOptions)
|
||||
defer e.Destroy()
|
||||
e.MarshalDoc("", reflect.ValueOf(v))
|
||||
e.Finish()
|
||||
p := NewComposer(e.Out)
|
||||
// Use the 3-stage dump pipeline with round-trip to preserve styles
|
||||
r := NewRepresenter(DefaultOptions)
|
||||
node := r.Represent("", reflect.ValueOf(v))
|
||||
d := NewDesolver(DefaultOptions)
|
||||
d.Desolve(node)
|
||||
s := NewSerializer(nil, DefaultOptions)
|
||||
var out []byte
|
||||
s.Emitter.SetOutputString(&out)
|
||||
s.Serialize(node)
|
||||
s.Finish()
|
||||
// Parse back to get styles
|
||||
p := NewComposer(out, nil)
|
||||
p.Textless = true
|
||||
defer p.Destroy()
|
||||
doc := p.Parse()
|
||||
doc := p.Compose()
|
||||
NewResolver(nil).Resolve(doc)
|
||||
*n = *doc.Content[0]
|
||||
return nil
|
||||
}
|
||||
@@ -350,14 +364,106 @@ func (n *Node) Dump(v any, opts ...Option) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e := NewRepresenter(noWriter, o)
|
||||
defer e.Destroy()
|
||||
e.MarshalDoc("", reflect.ValueOf(v))
|
||||
e.Finish()
|
||||
p := NewComposer(e.Out)
|
||||
// Use the 3-stage dump pipeline with round-trip to preserve styles
|
||||
r := NewRepresenter(o)
|
||||
node := r.Represent("", reflect.ValueOf(v))
|
||||
d := NewDesolver(o)
|
||||
d.Desolve(node)
|
||||
s := NewSerializer(nil, o)
|
||||
var out []byte
|
||||
s.Emitter.SetOutputString(&out)
|
||||
s.Serialize(node)
|
||||
s.Finish()
|
||||
// Parse back to get styles
|
||||
p := NewComposer(out, nil)
|
||||
p.Textless = true
|
||||
defer p.Destroy()
|
||||
doc := p.Parse()
|
||||
doc := p.Compose()
|
||||
NewResolver(nil).Resolve(doc)
|
||||
*n = *doc.Content[0]
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshaler interface may be implemented by types to customize their
|
||||
// behavior when being marshaled into a YAML document.
|
||||
type Marshaler interface {
|
||||
MarshalYAML() (any, error)
|
||||
}
|
||||
|
||||
// Unmarshaler is the interface implemented by types that can unmarshal
|
||||
// a YAML description of themselves.
|
||||
type Unmarshaler interface {
|
||||
UnmarshalYAML(node *Node) error
|
||||
}
|
||||
|
||||
// IsZeroer is used to check whether an object is zero to determine whether
|
||||
// it should be omitted when marshaling with the ,omitempty flag. One notable
|
||||
// implementation is [time.Time].
|
||||
type IsZeroer interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
// FromYAMLNode is a new interface that types can implement to customize
|
||||
// their unmarshaling behavior. It receives a Node directly and modifies
|
||||
// the receiver in place.
|
||||
// This is the preferred interface for new code.
|
||||
//
|
||||
// Note: This interface is reserved for the v4 API and is not yet fully
|
||||
// integrated into the current implementation.
|
||||
type FromYAMLNode interface {
|
||||
FromYAMLNode(*Node) error
|
||||
}
|
||||
|
||||
// ToYAMLNode is a new interface that types can implement to customize
|
||||
// their marshaling behavior. It returns a Node directly.
|
||||
// This is the preferred interface for new code.
|
||||
//
|
||||
// Note: This interface is reserved for the v4 API and is not yet fully
|
||||
// integrated into the current implementation.
|
||||
type ToYAMLNode interface {
|
||||
ToYAMLNode() (*Node, error)
|
||||
}
|
||||
|
||||
// isZero reports whether v represents the zero value for its type.
|
||||
// If v implements the IsZeroer interface, IsZero() is called.
|
||||
// Otherwise, zero is determined by checking type-specific conditions.
|
||||
// This is used to determine omitempty behavior when marshaling.
|
||||
func isZero(v reflect.Value) bool {
|
||||
kind := v.Kind()
|
||||
if z, ok := v.Interface().(IsZeroer); ok {
|
||||
if (kind == reflect.Pointer || kind == reflect.Interface) && v.IsNil() {
|
||||
return true
|
||||
}
|
||||
return z.IsZero()
|
||||
}
|
||||
switch kind {
|
||||
case reflect.String:
|
||||
return len(v.String()) == 0
|
||||
case reflect.Interface, reflect.Pointer:
|
||||
return v.IsNil()
|
||||
case reflect.Slice:
|
||||
return v.Len() == 0
|
||||
case reflect.Map:
|
||||
return v.Len() == 0
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Struct:
|
||||
vt := v.Type()
|
||||
for i := v.NumField() - 1; i >= 0; i-- {
|
||||
if vt.Field(i).PkgPath != "" {
|
||||
continue // Private field
|
||||
}
|
||||
if !isZero(v.Field(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user