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  }