github.com/mailru/activerecord@v1.12.2/pkg/serializer/mapstructure.go (about) 1 package serializer 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 "github.com/mailru/mapstructure" 8 9 "github.com/mailru/activerecord/pkg/serializer/errs" 10 ) 11 12 func MapstructureUnmarshal(data string, v any) error { 13 m := make(map[string]interface{}) 14 15 err := json.Unmarshal([]byte(data), &m) 16 if err != nil { 17 return fmt.Errorf("%w: %v", errs.ErrUnmarshalJSON, err) 18 } 19 20 config := &mapstructure.DecoderConfig{ 21 // Включает режим, при котором если какое-то поле не использовалось при декодировании, то возращается ошибка 22 ErrorUnused: true, 23 // Включает режим перезатирания, то есть при декодировании поля в целевой структуре сбрасываются до default value 24 // По умолчанию mapstructure пытается смержить 2 объекта 25 ZeroFields: true, 26 Result: v, 27 } 28 29 decoder, err := mapstructure.NewDecoder(config) 30 if err != nil { 31 return fmt.Errorf("%w: %v", errs.ErrMapstructureNewDecoder, err) 32 } 33 34 err = decoder.Decode(m) 35 if err != nil { 36 return fmt.Errorf("%w: %v", errs.ErrMapstructureDecode, err) 37 } 38 39 return nil 40 } 41 42 func MapstructureWeakUnmarshal(data string, v any) error { 43 var m map[string]interface{} 44 45 err := json.Unmarshal([]byte(data), &m) 46 if err != nil { 47 return fmt.Errorf("%w: %v", errs.ErrUnmarshalJSON, err) 48 } 49 50 config := &mapstructure.DecoderConfig{ 51 // Включает режим, при котором если какое-то поле не использовалось при декодировании, то возращается ошибка 52 ErrorUnused: true, 53 // Включает режим перезатирания, то есть при декодировании поля в целевой структуре сбрасываются до default value 54 // По умолчанию mapstructure пытается смержить 2 объекта 55 ZeroFields: true, 56 // Включает режим, нестрогой типизации 57 WeaklyTypedInput: true, 58 Result: v, 59 } 60 61 decoder, err := mapstructure.NewDecoder(config) 62 if err != nil { 63 return fmt.Errorf("%w: %v", errs.ErrMapstructureNewDecoder, err) 64 } 65 66 err = decoder.Decode(m) 67 if err != nil { 68 return fmt.Errorf("%w: %v", errs.ErrMapstructureDecode, err) 69 } 70 71 return nil 72 } 73 74 func MapstructureMarshal(v any) (string, error) { 75 m := make(map[string]interface{}) 76 77 err := mapstructure.Decode(v, &m) 78 if err != nil { 79 return "", fmt.Errorf("%w: %v", errs.ErrMapstructureEncode, err) 80 } 81 82 b, err := json.Marshal(m) 83 if err != nil { 84 return "", fmt.Errorf("%w: %v", errs.ErrMarshalJSON, err) 85 } 86 87 return string(b), nil 88 }