github.com/mailru/activerecord@v1.12.2/internal/pkg/parser/serializer.go (about)

     1  package parser
     2  
     3  import (
     4  	"go/ast"
     5  
     6  	"github.com/mailru/activerecord/internal/pkg/arerror"
     7  	"github.com/mailru/activerecord/internal/pkg/ds"
     8  )
     9  
    10  func ParseTypeSerializer(dst *ds.RecordPackage, serializerName string, t interface{}) (string, error) {
    11  	switch tv := t.(type) {
    12  	case *ast.Ident:
    13  		return tv.String(), nil
    14  	case *ast.ArrayType:
    15  		var err error
    16  
    17  		len := ""
    18  		if tv.Len != nil {
    19  			len, err = ParseTypeSerializer(dst, serializerName, tv.Len)
    20  			if err != nil {
    21  				return "", err
    22  			}
    23  		}
    24  
    25  		t, err := ParseTypeSerializer(dst, serializerName, tv.Elt)
    26  		if err != nil {
    27  			return "", err
    28  		}
    29  
    30  		return "[" + len + "]" + t, nil
    31  	case *ast.InterfaceType:
    32  		return "interface{}", nil
    33  	case *ast.StarExpr:
    34  		t, err := ParseTypeSerializer(dst, serializerName, tv.X)
    35  		if err != nil {
    36  			return "", err
    37  		}
    38  
    39  		return "*" + t, nil
    40  	case *ast.MapType:
    41  		k, err := ParseTypeSerializer(dst, serializerName, tv.Key)
    42  		if err != nil {
    43  			return "", nil
    44  		}
    45  
    46  		v, err := ParseTypeSerializer(dst, serializerName, tv.Value)
    47  		if err != nil {
    48  			return "", nil
    49  		}
    50  
    51  		return "map[" + k + "]" + v, nil
    52  	case *ast.SelectorExpr:
    53  		pName, err := ParseTypeSerializer(dst, serializerName, tv.X)
    54  		if err != nil {
    55  			return "", err
    56  		}
    57  
    58  		imp, err := dst.FindImportByPkg(pName)
    59  		if err != nil {
    60  			return "", &arerror.ErrParseSerializerTypeDecl{Name: serializerName, SerializerType: tv, Err: err}
    61  		}
    62  
    63  		reqImportName := imp.ImportName
    64  		if reqImportName == "" {
    65  			reqImportName = pName
    66  		}
    67  
    68  		return reqImportName + "." + tv.Sel.Name, nil
    69  	default:
    70  		return "", &arerror.ErrParseSerializerTypeDecl{Name: serializerName, SerializerType: tv, Err: arerror.ErrUnknown}
    71  	}
    72  }
    73  
    74  func ParseSerializer(dst *ds.RecordPackage, fields []*ast.Field) error {
    75  	defaultSerializerPkg := "github.com/mailru/activerecord/pkg/serializer"
    76  	for _, field := range fields {
    77  		if field.Names == nil || len(field.Names) != 1 {
    78  			return &arerror.ErrParseSerializerDecl{Err: arerror.ErrNameDeclaration}
    79  		}
    80  
    81  		newserializer := ds.SerializerDeclaration{
    82  			Name:        field.Names[0].Name,
    83  			ImportName:  "serializer" + field.Names[0].Name,
    84  			Pkg:         defaultSerializerPkg,
    85  			Marshaler:   field.Names[0].Name + "Marshal",
    86  			Unmarshaler: field.Names[0].Name + "Unmarshal",
    87  		}
    88  
    89  		tagParam, err := splitTag(field, NoCheckFlag, map[TagNameType]ParamValueRule{})
    90  		if err != nil {
    91  			return &arerror.ErrParseSerializerDecl{Name: newserializer.Name, Err: err}
    92  		}
    93  
    94  		for _, kv := range tagParam {
    95  			switch kv[0] {
    96  			case "pkg":
    97  				newserializer.Pkg = kv[1]
    98  			case "marshaler":
    99  				newserializer.Marshaler = kv[1]
   100  			case "unmarshaler":
   101  				newserializer.Unmarshaler = kv[1]
   102  			default:
   103  				return &arerror.ErrParseSerializerTagDecl{Name: newserializer.Name, TagName: kv[0], TagValue: kv[1], Err: arerror.ErrParseTagUnknown}
   104  			}
   105  		}
   106  
   107  		imp, err := dst.FindOrAddImport(newserializer.Pkg, newserializer.ImportName)
   108  		if err != nil {
   109  			return &arerror.ErrParseSerializerDecl{Name: newserializer.Name, Err: err}
   110  		}
   111  
   112  		newserializer.ImportName = imp.ImportName
   113  
   114  		newserializer.Type, err = ParseTypeSerializer(dst, newserializer.Name, field.Type)
   115  		if err != nil {
   116  			return &arerror.ErrParseSerializerDecl{Name: newserializer.Name, Err: err}
   117  		}
   118  
   119  		if err = dst.AddSerializer(newserializer); err != nil {
   120  			return err
   121  		}
   122  	}
   123  
   124  	return nil
   125  }