@@ -47,10 +47,11 @@ func DefaultDecoderOptions() DecoderOptions {
47
47
48
48
type hjsonParser struct {
49
49
DecoderOptions
50
- data []byte
51
- at int // The index of the current character
52
- ch byte // The current character
53
- structTypeCache map [reflect.Type ]structFieldMap
50
+ data []byte
51
+ at int // The index of the current character
52
+ ch byte // The current character
53
+ structTypeCache map [reflect.Type ]structFieldMap
54
+ willMarshalToJSON bool
54
55
}
55
56
56
57
var unmarshalerText = reflect .TypeOf ((* encoding .TextUnmarshaler )(nil )).Elem ()
@@ -326,7 +327,7 @@ func (p *hjsonParser) white() {
326
327
func (p * hjsonParser ) readTfnns (dest reflect.Value , t reflect.Type ) (interface {}, error ) {
327
328
328
329
// Hjson strings can be quoteless
329
- // returns string, json.Number, true, false, or null.
330
+ // returns string, ( json.Number or float64) , true, false, or null.
330
331
331
332
if isPunctuatorChar (p .ch ) {
332
333
return nil , p .errAt ("Found a punctuator character '" + string (p .ch ) + "' when expecting a quoteless string (check your syntax)" )
@@ -369,8 +370,12 @@ func (p *hjsonParser) readTfnns(dest reflect.Value, t reflect.Type) (interface{}
369
370
}
370
371
default :
371
372
if chf == '-' || chf >= '0' && chf <= '9' {
372
- // Always use json.Number because we will marshal to JSON.
373
- if n , err := tryParseNumber (value .Bytes (), false , true ); err == nil {
373
+ // Always use json.Number if we will marshal to JSON.
374
+ if n , err := tryParseNumber (
375
+ value .Bytes (),
376
+ false ,
377
+ p .willMarshalToJSON || p .DecoderOptions .UseJSONNumber ,
378
+ ); err == nil {
374
379
return n , nil
375
380
}
376
381
}
@@ -477,7 +482,7 @@ func (p *hjsonParser) readObject(
477
482
) (value interface {}, err error ) {
478
483
// Parse an object value.
479
484
480
- var object orderedMap
485
+ object := NewOrderedMap ()
481
486
482
487
if ! withoutBraces {
483
488
// assuming ch == '{'
@@ -562,7 +567,7 @@ func (p *hjsonParser) readObject(
562
567
if val , err = p .readValue (newDest , elemType ); err != nil {
563
568
return nil , err
564
569
}
565
- object = append ( object , keyVal { key , val } )
570
+ object . Set ( key , val )
566
571
p .white ()
567
572
// in Hjson the comma is optional and trailing commas are allowed
568
573
if p .ch == ',' {
@@ -652,18 +657,27 @@ func Unmarshal(data []byte, v interface{}) error {
652
657
return UnmarshalWithOptions (data , v , DefaultDecoderOptions ())
653
658
}
654
659
655
- func orderedUnmarshal (data []byte , v interface {}, options DecoderOptions ) (interface {}, error ) {
660
+ func orderedUnmarshal (
661
+ data []byte ,
662
+ v interface {},
663
+ options DecoderOptions ,
664
+ willMarshalToJSON bool ,
665
+ ) (
666
+ interface {},
667
+ error ,
668
+ ) {
656
669
rv := reflect .ValueOf (v )
657
670
if rv .Kind () != reflect .Ptr || rv .IsNil () {
658
671
return nil , fmt .Errorf ("Cannot unmarshal into non-pointer %v" , reflect .TypeOf (v ))
659
672
}
660
673
661
674
parser := & hjsonParser {
662
- DecoderOptions : options ,
663
- data : data ,
664
- at : 0 ,
665
- ch : ' ' ,
666
- structTypeCache : map [reflect.Type ]structFieldMap {},
675
+ DecoderOptions : options ,
676
+ data : data ,
677
+ at : 0 ,
678
+ ch : ' ' ,
679
+ structTypeCache : map [reflect.Type ]structFieldMap {},
680
+ willMarshalToJSON : willMarshalToJSON ,
667
681
}
668
682
parser .resetAt ()
669
683
value , err := parser .rootValue (rv )
@@ -677,17 +691,37 @@ func orderedUnmarshal(data []byte, v interface{}, options DecoderOptions) (inter
677
691
// UnmarshalWithOptions parses the Hjson-encoded data and stores the result
678
692
// in the value pointed to by v.
679
693
//
680
- // Internally the Hjson input is converted to JSON, which is then used as input
681
- // to the function json.Unmarshal().
694
+ // Unless v is of type *hjson.OrderedMap, the Hjson input is internally
695
+ // converted to JSON, which is then used as input to the function
696
+ // json.Unmarshal().
682
697
//
683
698
// For more details about the output from this function, see the documentation
684
699
// for json.Unmarshal().
685
700
func UnmarshalWithOptions (data []byte , v interface {}, options DecoderOptions ) error {
686
- value , err := orderedUnmarshal (data , v , options )
701
+ inOM , destinationIsOrderedMap := v .(* OrderedMap )
702
+ if ! destinationIsOrderedMap {
703
+ pInOM , ok := v .(* * OrderedMap )
704
+ if ok {
705
+ destinationIsOrderedMap = true
706
+ inOM = & OrderedMap {}
707
+ * pInOM = inOM
708
+ }
709
+ }
710
+
711
+ value , err := orderedUnmarshal (data , v , options , ! destinationIsOrderedMap )
687
712
if err != nil {
688
713
return err
689
714
}
690
715
716
+ if destinationIsOrderedMap {
717
+ if outOM , ok := value .(* OrderedMap ); ok {
718
+ * inOM = * outOM
719
+ return nil
720
+ }
721
+ return fmt .Errorf ("Cannot unmarshal into hjson.OrderedMap: Try %v as destination instead" ,
722
+ reflect .TypeOf (v ))
723
+ }
724
+
691
725
// Convert to JSON so we can let json.Unmarshal() handle all destination
692
726
// types (including interfaces json.Unmarshaler and encoding.TextUnmarshaler)
693
727
// and merging.
0 commit comments