Skip to content

Commit 8e076d9

Browse files
Merge pull request #1 from taustgen-wework/v3
Updates to yaml allowing decoding into structs and maintaining field positions and comments.
2 parents 496545a + 2fb0426 commit 8e076d9

9 files changed

+266
-61
lines changed

decode.go

+63
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,43 @@ func isStringMap(n *Node) bool {
851851
return true
852852
}
853853

854+
//
855+
856+
// StuctMeta can be added to a struct and holds the comments and field ordering for that struct
857+
type StructMeta interface {
858+
// Returns the fields in proper order
859+
GetFieldsIndex() []fieldInfo
860+
861+
// Returns the head line and foot comments for the field
862+
GetComments() [][]comments
863+
}
864+
865+
// structMeta implements the StructMeta interface
866+
type structMeta struct {
867+
FieldsIndex []fieldInfo
868+
Comments [][]comments
869+
}
870+
871+
// comments holds the 3 possible comments for a node.
872+
type comments struct {
873+
head []byte
874+
line []byte
875+
foot []byte
876+
}
877+
878+
const yamlMeta = "yaml_meta"
879+
880+
func (s *structMeta) GetFieldsIndex() []fieldInfo {
881+
return s.FieldsIndex
882+
}
883+
884+
func (s *structMeta) GetComments() [][]comments {
885+
return s.Comments
886+
}
887+
854888
func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
889+
fieldsIndex := make([]fieldInfo, 0)
890+
com := make([][]comments, 0)
855891
sinfo, err := getStructInfo(out.Type())
856892
if err != nil {
857893
panic(err)
@@ -900,6 +936,21 @@ func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
900936
field = d.fieldByIndex(n, out, info.Inline)
901937
}
902938
d.unmarshal(n.Content[i+1], field)
939+
940+
keyComments := comments{
941+
head: []byte(ni.HeadComment),
942+
line: []byte(ni.LineComment),
943+
foot: []byte(ni.FootComment),
944+
}
945+
valComments := comments{
946+
head: []byte(n.Content[i+1].HeadComment),
947+
line: []byte(n.Content[i+1].LineComment),
948+
foot: []byte(n.Content[i+1].FootComment),
949+
}
950+
951+
fieldsIndex = append(fieldsIndex, info)
952+
com = append(com, []comments{keyComments, valComments})
953+
903954
} else if sinfo.InlineMap != -1 {
904955
if inlineMap.IsNil() {
905956
inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
@@ -911,6 +962,18 @@ func (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {
911962
d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.Line, name.String(), out.Type()))
912963
}
913964
}
965+
966+
// This change is populating yamlMeta field with the with field order and comments
967+
if idxInfo, idxOk := sinfo.FieldsMap[yamlMeta]; idxOk {
968+
idxField := out.Field(idxInfo.Num)
969+
fValue := &structMeta{
970+
FieldsIndex: fieldsIndex,
971+
Comments: com,
972+
}
973+
974+
idxField.Set(reflect.ValueOf(fValue))
975+
}
976+
914977
return true
915978
}
916979

emitterc.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool
241241
emitter.indent += 2
242242
} else {
243243
// Everything else aligns to the chosen indentation.
244-
emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent)
244+
emitter.indent = emitter.best_indent * ((emitter.indent + emitter.best_indent) / emitter.best_indent)
245245
}
246246
}
247247
return true
@@ -727,14 +727,17 @@ func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_e
727727

728728
// Expect a block item node.
729729
func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
730-
if first {
730+
if first && !emitter.sequenceUndent {
731731
if !yaml_emitter_increase_indent(emitter, false, false) {
732732
return false
733733
}
734734
}
735735
if event.typ == yaml_SEQUENCE_END_EVENT {
736-
emitter.indent = emitter.indents[len(emitter.indents)-1]
737-
emitter.indents = emitter.indents[:len(emitter.indents)-1]
736+
if !emitter.sequenceUndent {
737+
emitter.indent = emitter.indents[len(emitter.indents)-1]
738+
emitter.indents = emitter.indents[:len(emitter.indents)-1]
739+
}
740+
738741
emitter.state = emitter.states[len(emitter.states)-1]
739742
emitter.states = emitter.states[:len(emitter.states)-1]
740743
return true
@@ -1612,7 +1615,6 @@ func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allo
16121615
return false
16131616
}
16141617
}
1615-
16161618
spaces := false
16171619
breaks := false
16181620
for i := 0; i < len(value); {

0 commit comments

Comments
 (0)