88package yaml
99
1010import (
11+ "bufio"
12+ "bytes"
1113 "fmt"
1214 "reflect"
1315 "strconv"
@@ -16,6 +18,8 @@ import (
1618
1719 "github.com/pkg/errors"
1820 goyaml "gopkg.in/yaml.v2" // import the YAML library from https://github.com/go-yaml/yaml
21+
22+ "github.com/spatialcurrent/go-simple-serializer/pkg/splitter"
1923)
2024
2125// UnmarshalType parses a slice of bytes into an object of a given type.
@@ -27,21 +31,46 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
2731 return nil , ErrEmptyInput
2832 }
2933
30- switch string (b ) {
31- case "true" :
34+ if bytes .Equal (b , True ) {
3235 if outputType .Kind () != reflect .Bool {
3336 return nil , & ErrInvalidKind {Value : outputType , Expected : []reflect.Kind {reflect .Bool }}
3437 }
3538 return true , nil
36- case "false" :
39+ }
40+ if bytes .Equal (b , False ) {
3741 if outputType .Kind () != reflect .Bool {
3842 return nil , & ErrInvalidKind {Value : outputType , Expected : []reflect.Kind {reflect .Bool }}
3943 }
4044 return false , nil
41- case "null" :
45+ }
46+ if bytes .Equal (b , Null ) {
4247 return nil , nil
4348 }
4449
50+ if bytes .HasPrefix (b , BoundaryMarker ) {
51+ if outputType .Kind () != reflect .Slice {
52+ return nil , & ErrInvalidKind {Value : outputType , Expected : []reflect.Kind {reflect .Slice }}
53+ }
54+ s := bufio .NewScanner (bytes .NewReader (b ))
55+ s .Split (splitter .ScanDocuments (BoundaryMarker , true ))
56+ out := reflect .MakeSlice (outputType , 0 , 0 )
57+ i := 0
58+ for s .Scan () {
59+ if d := s .Bytes (); len (d ) > 0 {
60+ obj , err := UnmarshalType (d , outputType .Elem ())
61+ if err != nil {
62+ return out .Interface (), errors .Wrapf (err , "error scanning document %d" , i )
63+ }
64+ out = reflect .Append (out , reflect .ValueOf (obj ))
65+ i ++
66+ }
67+ }
68+ if err := s .Err (); err != nil {
69+ return out .Interface (), errors .Wrap (err , fmt .Sprintf ("error scanning YAML %q" , string (b )))
70+ }
71+ return out .Interface (), nil
72+ }
73+
4574 first , _ := utf8 .DecodeRune (b )
4675 if first == utf8 .RuneError {
4776 return nil , ErrInvalidRune
@@ -56,7 +85,7 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
5685 ptr .Elem ().Set (reflect .MakeSlice (outputType , 0 , 0 ))
5786 err := goyaml .Unmarshal (b , ptr .Interface ())
5887 if err != nil {
59- return nil , errors .Wrap (err , fmt .Sprintf ("error unmarshaling JSON %q" , string (b )))
88+ return nil , errors .Wrap (err , fmt .Sprintf ("error unmarshaling YAML %q" , string (b )))
6089 }
6190 return ptr .Elem ().Interface (), nil
6291 case '{' :
@@ -67,7 +96,7 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
6796 ptr .Elem ().Set (reflect .MakeMap (outputType ))
6897 err := goyaml .Unmarshal (b , ptr .Interface ())
6998 if err != nil {
70- return nil , errors .Wrap (err , fmt .Sprintf ("error unmarshaling JSON %q" , string (b )))
99+ return nil , errors .Wrap (err , fmt .Sprintf ("error unmarshaling YAML %q" , string (b )))
71100 }
72101 return ptr .Elem ().Interface (), nil
73102 case '"' :
@@ -77,7 +106,7 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
77106 obj := ""
78107 err := goyaml .Unmarshal (b , & obj )
79108 if err != nil {
80- return nil , errors .Wrap (err , fmt .Sprintf ("error unmarshaling JSON %q" , string (b )))
109+ return nil , errors .Wrap (err , fmt .Sprintf ("error unmarshaling YAML %q" , string (b )))
81110 }
82111 return obj , nil
83112 }
@@ -109,5 +138,6 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
109138 }
110139 return f , nil
111140 }
141+
112142 return string (b ), nil
113143}
0 commit comments