8
8
package yaml
9
9
10
10
import (
11
+ "bufio"
12
+ "bytes"
11
13
"fmt"
12
14
"reflect"
13
15
"strconv"
@@ -16,6 +18,8 @@ import (
16
18
17
19
"github.com/pkg/errors"
18
20
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"
19
23
)
20
24
21
25
// 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) {
27
31
return nil , ErrEmptyInput
28
32
}
29
33
30
- switch string (b ) {
31
- case "true" :
34
+ if bytes .Equal (b , True ) {
32
35
if outputType .Kind () != reflect .Bool {
33
36
return nil , & ErrInvalidKind {Value : outputType , Expected : []reflect.Kind {reflect .Bool }}
34
37
}
35
38
return true , nil
36
- case "false" :
39
+ }
40
+ if bytes .Equal (b , False ) {
37
41
if outputType .Kind () != reflect .Bool {
38
42
return nil , & ErrInvalidKind {Value : outputType , Expected : []reflect.Kind {reflect .Bool }}
39
43
}
40
44
return false , nil
41
- case "null" :
45
+ }
46
+ if bytes .Equal (b , Null ) {
42
47
return nil , nil
43
48
}
44
49
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
+
45
74
first , _ := utf8 .DecodeRune (b )
46
75
if first == utf8 .RuneError {
47
76
return nil , ErrInvalidRune
@@ -56,7 +85,7 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
56
85
ptr .Elem ().Set (reflect .MakeSlice (outputType , 0 , 0 ))
57
86
err := goyaml .Unmarshal (b , ptr .Interface ())
58
87
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 )))
60
89
}
61
90
return ptr .Elem ().Interface (), nil
62
91
case '{' :
@@ -67,7 +96,7 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
67
96
ptr .Elem ().Set (reflect .MakeMap (outputType ))
68
97
err := goyaml .Unmarshal (b , ptr .Interface ())
69
98
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 )))
71
100
}
72
101
return ptr .Elem ().Interface (), nil
73
102
case '"' :
@@ -77,7 +106,7 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
77
106
obj := ""
78
107
err := goyaml .Unmarshal (b , & obj )
79
108
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 )))
81
110
}
82
111
return obj , nil
83
112
}
@@ -109,5 +138,6 @@ func UnmarshalType(b []byte, outputType reflect.Type) (interface{}, error) {
109
138
}
110
139
return f , nil
111
140
}
141
+
112
142
return string (b ), nil
113
143
}
0 commit comments