@@ -36,83 +36,46 @@ func unescapePropertyText(in string) string {
3636}
3737
3838// Deserialize reads in an object from a string given format
39- func Deserialize (input string , format string , input_header []string , input_comment string , output interface {}) error {
39+ func Deserialize (input string , format string , input_header []string , input_comment string , output_type reflect. Type , verbose bool ) ( interface {}, error ) {
4040
4141 if format == "csv" || format == "tsv" {
42- switch output_slice := output .(type ) {
43- case * []map [string ]string :
44- reader := csv .NewReader (strings .NewReader (input ))
45- if format == "tsv" {
46- reader .Comma = '\t'
47- }
48- if len (input_comment ) > 1 {
49- return errors .New ("go's encoding/csv package only supports single character comment characters" )
50- } else if len (input_comment ) == 1 {
51- reader .Comment = []rune (input_comment )[0 ]
52- }
53- if len (input_header ) == 0 {
54- h , err := reader .Read ()
55- if err != nil {
56- if err != io .EOF {
57- return errors .Wrap (err , "Error reading header from input with format csv" )
58- }
59- }
60- input_header = h
61- }
62- for {
63- inRow , err := reader .Read ()
64- if err != nil {
65- if err == io .EOF {
66- break
67- } else {
68- return errors .Wrap (err , "Error reading row from input with format csv" )
69- }
42+ output := reflect .MakeSlice (output_type , 0 , 0 )
43+ reader := csv .NewReader (strings .NewReader (input ))
44+ if format == "tsv" {
45+ reader .Comma = '\t'
46+ }
47+ if len (input_comment ) > 1 {
48+ return nil , errors .New ("go's encoding/csv package only supports single character comment characters" )
49+ } else if len (input_comment ) == 1 {
50+ reader .Comment = []rune (input_comment )[0 ]
51+ }
52+ if len (input_header ) == 0 {
53+ h , err := reader .Read ()
54+ if err != nil {
55+ if err != io .EOF {
56+ return nil , errors .Wrap (err , "Error reading header from input with format csv" )
7057 }
71- * output_slice = append (* output_slice , RowToMapOfStrings (input_header , inRow ))
72- }
73- case * []map [string ]interface {}:
74- reader := csv .NewReader (strings .NewReader (input ))
75- if format == "tsv" {
76- reader .Comma = '\t'
7758 }
78- if len (input_comment ) > 1 {
79- return errors .New ("go's encoding/csv package only supports single character comment characters" )
80- } else if len (input_comment ) == 1 {
81- reader .Comment = []rune (input_comment )[0 ]
82- }
83- if len (input_header ) == 0 {
84- h , err := reader .Read ()
85- if err != nil {
86- if err != io .EOF {
87- return errors .Wrap (err , "Error reading header from input with format csv" )
88- }
59+ input_header = h
60+ }
61+ for {
62+ inRow , err := reader .Read ()
63+ if err != nil {
64+ if err == io .EOF {
65+ break
66+ } else {
67+ return nil , errors .Wrap (err , "Error reading row from input with format csv" )
8968 }
90- input_header = h
9169 }
92- for {
93- inRow , err := reader .Read ()
94- if err != nil {
95- if err == io .EOF {
96- break
97- } else {
98- return errors .Wrap (err , "Error reading row from input with format csv" )
99- }
100- }
101- * output_slice = append (* output_slice , RowToMapOfInterfaces (input_header , inRow ))
70+ m := reflect .MakeMap (reflect .TypeOf (output .Elem ()))
71+ for i , h := range input_header {
72+ m .SetMapIndex (reflect .ValueOf (strings .ToLower (h )), reflect .ValueOf (inRow [i ]))
10273 }
103- default :
104- return errors .New ("Cannot deserialize to type " + fmt .Sprint (reflect .ValueOf (output )))
74+ output = reflect .Append (output , m )
10575 }
76+ return output .Interface (), nil
10677 } else if format == "properties" {
107- m := reflect .ValueOf (output )
108- if m .Kind () == reflect .Ptr {
109- if m .Elem ().Kind () != reflect .Map {
110- return errors .New ("Output is not of kind map." )
111- }
112- m = m .Elem ()
113- } else if m .Kind () != reflect .Map {
114- return errors .New ("Output is not of kind map." )
115- }
78+ m := reflect .MakeMap (output_type )
11679 if len (input_comment ) == 0 {
11780 input_comment = "#"
11881 }
@@ -136,104 +99,94 @@ func Deserialize(input string, format string, input_header []string, input_comme
13699 }
137100 }
138101 if len (propertyName ) == 0 {
139- return errors .New ("error deserializing properties for property " + property )
102+ return nil , errors .New ("error deserializing properties for property " + property )
140103 }
141104 m .SetMapIndex (reflect .ValueOf (unescapePropertyText (strings .TrimSpace (propertyName ))), reflect .ValueOf (unescapePropertyText (strings .TrimSpace (propertyValue ))))
142105 property = ""
143106 }
144107 }
145108 }
109+ return m .Interface (), nil
146110 } else if format == "bson" {
147- return bson .Unmarshal ([]byte (input ), output )
111+ if output_type .Kind () == reflect .Map {
112+ ptr := reflect .New (output_type )
113+ ptr .Elem ().Set (reflect .MakeMap (output_type ))
114+ err := bson .Unmarshal ([]byte (input ), ptr .Interface ())
115+ return ptr .Elem ().Interface (), err
116+ } else {
117+ return nil , errors .New ("Invalid output type for json " + fmt .Sprint (output_type ))
118+ }
148119 } else if format == "json" {
149- return json .Unmarshal ([]byte (input ), output )
120+ if output_type .Kind () == reflect .Map {
121+ ptr := reflect .New (output_type )
122+ ptr .Elem ().Set (reflect .MakeMap (output_type ))
123+ err := json .Unmarshal ([]byte (input ), ptr .Interface ())
124+ return ptr .Elem ().Interface (), err
125+ } else if output_type .Kind () == reflect .Slice {
126+ ptr := reflect .New (output_type )
127+ ptr .Elem ().Set (reflect .MakeSlice (output_type , 0 , 0 ))
128+ err := json .Unmarshal ([]byte (input ), ptr .Interface ())
129+ return ptr .Elem ().Interface (), err
130+ } else {
131+ return nil , errors .New ("Invalid output type for json " + fmt .Sprint (output_type ))
132+ }
150133 } else if format == "jsonl" {
151-
152- //s.Interface()(type)
153- // reflect.TypeOf(s).Elem()
154-
155- /*s := reflect.ValueOf(output)
156- if s.Kind() == reflect.Ptr {
157- fmt.Println("s.Interface():", s.Interface())
158- s = reflect.Indirect(s).Elem()
159- if s.Kind() != reflect.Slice {
160- return errors.New("Output is not of kind slice.")
161- }
162- } else if s.Kind() != reflect.Slice {
163- return errors.New("Output is not of kind slice.")
164- }*/
165-
166- //fmt.Println("reflect.TypeOf(output)", reflect.TypeOf(output))
167-
168- switch output_slice := output .(type ) {
169- case * []map [string ]string :
170- //output_slice := s.Interface().(*[]map[string]string)
171- scanner := bufio .NewScanner (strings .NewReader (input ))
172- scanner .Split (bufio .ScanLines )
173- for scanner .Scan () {
174- line := strings .TrimSpace (scanner .Text ())
175- if len (input_comment ) == 0 || ! strings .HasPrefix (line , input_comment ) {
176- obj := map [string ]string {}
177- err := json .Unmarshal ([]byte (line ), & obj )
178- if err != nil {
179- return errors .Wrap (err , "Error reading object from JSON line" )
180- }
181- * output_slice = append (* output_slice , obj )
182- }
183- }
184- case * []map [string ]interface {}:
185- //output_slice := s.Interface().(*[]map[string]interface{})
186- scanner := bufio .NewScanner (strings .NewReader (input ))
187- scanner .Split (bufio .ScanLines )
188- for scanner .Scan () {
189- line := strings .TrimSpace (scanner .Text ())
190- if len (input_comment ) == 0 || ! strings .HasPrefix (line , input_comment ) {
191- obj := map [string ]interface {}{}
192- err := json .Unmarshal ([]byte (line ), & obj )
193- if err != nil {
194- return errors .Wrap (err , "Error reading object from JSON line" )
195- }
196- * output_slice = append (* output_slice , obj )
197- }
198- }
199- case []map [string ]interface {}:
200- //output_slice := s.Interface().([]map[string]interface{})
201- scanner := bufio .NewScanner (strings .NewReader (input ))
202- scanner .Split (bufio .ScanLines )
203- for scanner .Scan () {
204- line := strings .TrimSpace (scanner .Text ())
205- if len (input_comment ) == 0 || ! strings .HasPrefix (line , input_comment ) {
206- obj := map [string ]interface {}{}
207- err := json .Unmarshal ([]byte (line ), & obj )
208- if err != nil {
209- return errors .Wrap (err , "Error reading object from JSON line" )
210- }
211- output_slice = append (output_slice , obj )
134+ output := reflect .MakeSlice (output_type , 0 , 0 )
135+ scanner := bufio .NewScanner (strings .NewReader (input ))
136+ scanner .Split (bufio .ScanLines )
137+ for scanner .Scan () {
138+ line := strings .TrimSpace (scanner .Text ())
139+ if len (input_comment ) == 0 || ! strings .HasPrefix (line , input_comment ) {
140+ obj := reflect .MakeMap (output_type .Elem ())
141+ err := json .Unmarshal ([]byte (line ), obj .Interface ())
142+ if err != nil {
143+ return nil , errors .Wrap (err , "Error reading object from JSON line" )
212144 }
145+ output = reflect .Append (output , obj )
213146 }
214- default :
215- return errors .New ("Cannot deserialize to type " + fmt .Sprint (reflect .TypeOf (output ).String ()))
216147 }
148+ return output , nil
217149 } else if format == "hcl" {
150+ ptr := reflect .New (output_type )
151+ ptr .Elem ().Set (reflect .MakeMap (output_type ))
218152 obj , err := hcl .Parse (input )
219153 if err != nil {
220- return errors .Wrap (err , "Error parsing hcl" )
154+ return nil , errors .Wrap (err , "Error parsing hcl" )
221155 }
222- if err := hcl .DecodeObject (output , obj ); err != nil {
223- return errors .Wrap (err , "Error decoding hcl" )
156+ if err := hcl .DecodeObject (ptr . Interface () , obj ); err != nil {
157+ return nil , errors .Wrap (err , "Error decoding hcl" )
224158 }
159+ return ptr .Elem ().Interface (), nil
225160 } else if format == "hcl2" {
226161 file , diags := hclsyntax .ParseConfig ([]byte (input ), "<stdin>" , hcl2.Pos {Byte : 0 , Line : 1 , Column : 1 })
227162 if diags .HasErrors () {
228- return errors .Wrap (errors .New (diags .Error ()), "Error parsing hcl2" )
163+ return nil , errors .Wrap (errors .New (diags .Error ()), "Error parsing hcl2" )
229164 }
230- output = & file .Body
165+ return & file .Body , nil
231166 } else if format == "toml" {
232- _ , err := toml .Decode (input , output )
233- return err
167+ if output_type .Kind () == reflect .Map {
168+ ptr := reflect .New (output_type )
169+ ptr .Elem ().Set (reflect .MakeMap (output_type ))
170+ _ , err := toml .Decode (input , ptr .Interface ())
171+ return ptr .Elem ().Interface (), err
172+ } else {
173+ return nil , errors .New ("Invalid output type for toml " + fmt .Sprint (output_type ))
174+ }
234175 } else if format == "yaml" {
235- return yaml .Unmarshal ([]byte (input ), output )
176+ if output_type .Kind () == reflect .Map {
177+ ptr := reflect .New (output_type )
178+ ptr .Elem ().Set (reflect .MakeMap (output_type ))
179+ err := yaml .Unmarshal ([]byte (input ), ptr .Interface ())
180+ return ptr .Elem ().Interface (), err
181+ } else if output_type .Kind () == reflect .Slice {
182+ ptr := reflect .New (output_type )
183+ ptr .Elem ().Set (reflect .MakeSlice (output_type , 0 , 0 ))
184+ err := yaml .Unmarshal ([]byte (input ), ptr .Interface ())
185+ return StringifyMapKeys (ptr .Elem ().Interface ()), err
186+ } else {
187+ return nil , errors .New ("Invalid output type for yaml " + fmt .Sprint (output_type ))
188+ }
236189 }
237190
238- return nil
191+ return nil , nil
239192}
0 commit comments