github.com/qiniu/go-sdk/v7@v7.27.0/internal/api-generator/multipart.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/dave/jennifer/jen"
     7  	"github.com/iancoleman/strcase"
     8  )
     9  
    10  type (
    11  	MultipartFormFields struct {
    12  		Named []NamedMultipartFormField `yaml:"named_fields,omitempty"`
    13  		Free  *FreeMultipartFormFields  `yaml:"free_fields,omitempty"`
    14  	}
    15  
    16  	NamedMultipartFormField struct {
    17  		FieldName          string                 `yaml:"field_name,omitempty"`
    18  		FieldCamelCaseName string                 `yaml:"field_camel_case_name,omitempty"`
    19  		FieldSnakeCaseName string                 `yaml:"field_snake_case_name,omitempty"`
    20  		Key                string                 `yaml:"key,omitempty"`
    21  		Type               *MultipartFormDataType `yaml:"type,omitempty"`
    22  		Documentation      string                 `yaml:"documentation,omitempty"`
    23  		ServiceBucket      *ServiceBucketType     `yaml:"service_bucket,omitempty"`
    24  		ServiceObject      *ServiceObjectType     `yaml:"service_object,omitempty"`
    25  		Optional           *OptionalType          `yaml:"optional,omitempty"`
    26  	}
    27  
    28  	FreeMultipartFormFields struct {
    29  		FieldName          string `yaml:"field_name,omitempty"`
    30  		FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"`
    31  		FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"`
    32  		Documentation      string `yaml:"documentation,omitempty"`
    33  	}
    34  )
    35  
    36  func (field *NamedMultipartFormField) camelCaseName() string {
    37  	if field.FieldCamelCaseName != "" {
    38  		return field.FieldCamelCaseName
    39  	}
    40  	return strcase.ToCamel(field.FieldName)
    41  }
    42  
    43  func (field *FreeMultipartFormFields) camelCaseName() string {
    44  	if field.FieldCamelCaseName != "" {
    45  		return field.FieldCamelCaseName
    46  	}
    47  	return strcase.ToCamel(field.FieldName)
    48  }
    49  
    50  func (mff *MultipartFormFields) addFields(group *jen.Group) error {
    51  	for _, named := range mff.Named {
    52  		fieldName := named.camelCaseName()
    53  		code, err := named.Type.AddTypeToStatement(jen.Id(fieldName), named.Optional.ToOptionalType() == OptionalTypeNullable)
    54  		if err != nil {
    55  			return err
    56  		}
    57  		group.Add(code)
    58  	}
    59  	if free := mff.Free; free != nil {
    60  		group.Add(jen.Id(free.camelCaseName()).Map(jen.String()).String())
    61  	}
    62  	return nil
    63  }
    64  
    65  func (mff *MultipartFormFields) addGetBucketNameFunc(group *jen.Group, structName string) (bool, error) {
    66  	field := mff.getServiceBucketField()
    67  
    68  	if field == nil || field.ServiceBucket.ToServiceBucketType() == ServiceBucketTypeNone {
    69  		return false, nil
    70  	} else if field.Type.ToMultipartFormDataType() != MultipartFormDataTypeString && field.Type.ToMultipartFormDataType() != MultipartFormDataTypeUploadToken {
    71  		panic(fmt.Sprintf("service bucket field must be string: %s", field.FieldName))
    72  	}
    73  
    74  	group.Add(jen.Func().
    75  		Params(jen.Id("form").Op("*").Id(structName)).
    76  		Id("getBucketName").
    77  		Params(jen.Id("ctx").Qual("context", "Context")).
    78  		Params(jen.String(), jen.Error()).
    79  		BlockFunc(func(group *jen.Group) {
    80  			fieldName := field.camelCaseName()
    81  			switch field.ServiceBucket.ToServiceBucketType() {
    82  			case ServiceBucketTypePlainText:
    83  				group.Add(jen.Return(jen.Id("form").Dot(fieldName), jen.Nil()))
    84  			case ServiceBucketTypeEntry:
    85  				group.Add(
    86  					jen.Return(
    87  						jen.Qual("strings", "SplitN").
    88  							Call(jen.Id("form").Dot(fieldName), jen.Lit(":"), jen.Lit(2)).
    89  							Index(jen.Lit(0)),
    90  						jen.Nil(),
    91  					),
    92  				)
    93  			case ServiceBucketTypeUploadToken:
    94  				group.Add(
    95  					jen.Id("putPolicy").
    96  						Op(",").
    97  						Err().
    98  						Op(":=").
    99  						Id("form").
   100  						Dot(fieldName).
   101  						Dot("GetPutPolicy").
   102  						Call(jen.Id("ctx")),
   103  				)
   104  				group.Add(
   105  					jen.If(jen.Err().Op("!=").Nil()).
   106  						BlockFunc(func(group *jen.Group) {
   107  							group.Add(jen.Return(jen.Lit(""), jen.Err()))
   108  						}).
   109  						Else().
   110  						BlockFunc(func(group *jen.Group) {
   111  							group.Add(jen.Return(jen.Id("putPolicy").Dot("GetBucketName").Call()))
   112  						}),
   113  				)
   114  			default:
   115  				panic("unknown ServiceBucketType")
   116  			}
   117  		}))
   118  	return true, nil
   119  }
   120  
   121  func (mff *MultipartFormFields) addGetObjectNameFunc(group *jen.Group, structName string) (bool, error) {
   122  	field := mff.getServiceObjectField()
   123  
   124  	if field == nil || field.ServiceObject.ToServiceObjectType() == ServiceObjectTypeNone {
   125  		return false, nil
   126  	} else if field.Type.ToMultipartFormDataType() != MultipartFormDataTypeString {
   127  		panic(fmt.Sprintf("service object field must be string: %s", field.FieldName))
   128  	}
   129  
   130  	group.Add(jen.Func().
   131  		Params(jen.Id("form").Op("*").Id(structName)).
   132  		Id("getObjectName").
   133  		Params().
   134  		Params(jen.String()).
   135  		BlockFunc(func(group *jen.Group) {
   136  			fieldName := field.camelCaseName()
   137  			switch field.ServiceObject.ToServiceObjectType() {
   138  			case ServiceObjectTypePlainText:
   139  				if field.Optional.ToOptionalType() == OptionalTypeNullable {
   140  					group.Add(jen.Var().Id("objectName").String())
   141  					group.Add(jen.If(jen.Id("form").Dot(fieldName).Op("!=").Nil()).BlockFunc(func(group *jen.Group) {
   142  						group.Add(jen.Id("objectName").Op("=").Op("*").Id("form").Dot(fieldName))
   143  					}))
   144  					group.Add(jen.Return(jen.Id("objectName")))
   145  				} else {
   146  					group.Return(jen.Id("form").Dot(fieldName))
   147  				}
   148  			case ServiceObjectTypeEntry:
   149  				group.Add(
   150  					jen.Id("parts").
   151  						Op(":=").
   152  						Qual("strings", "SplitN").
   153  						Call(jen.Id("form").Dot(fieldName), jen.Lit(":"), jen.Lit(2)))
   154  				group.Add(jen.If(jen.Len(jen.Id("parts")).Op(">").Lit(1)), jen.BlockFunc(func(group *jen.Group) {
   155  					group.Return(jen.Id("parts").Index(jen.Lit(1)))
   156  				}))
   157  				group.Add(jen.Return(jen.Lit("")))
   158  			default:
   159  				panic("unknown ServiceObjectType")
   160  			}
   161  		}))
   162  	return true, nil
   163  }
   164  
   165  func (mff *MultipartFormFields) addBuildFunc(group *jen.Group, structName string) error {
   166  	var err error
   167  	group.Add(
   168  		jen.Func().
   169  			Params(jen.Id("form").Op("*").Id(structName)).
   170  			Id("build").
   171  			Params(jen.Id("ctx").Qual("context", "Context")).
   172  			Params(jen.Op("*").Qual(PackageNameHTTPClient, "MultipartForm"), jen.Error()).
   173  			BlockFunc(func(group *jen.Group) {
   174  				group.Add(
   175  					jen.Id("multipartForm").
   176  						Op(":=").
   177  						New(jen.Qual(PackageNameHTTPClient, "MultipartForm")),
   178  				)
   179  				for _, named := range mff.Named {
   180  					var zeroValue interface{}
   181  					if named.Optional.ToOptionalType() != OptionalTypeNullable {
   182  						zeroValue, err = named.Type.ZeroValue()
   183  					}
   184  					if err != nil {
   185  						return
   186  					}
   187  					fieldName := named.camelCaseName()
   188  					field := jen.Id("form").Dot(fieldName)
   189  					var cond *jen.Statement
   190  					if named.Type.ToMultipartFormDataType() == MultipartFormDataTypeBinaryData {
   191  						cond = field.Clone().Dot("Data").Op("!=").Nil()
   192  					} else if zeroValue == nil {
   193  						cond = field.Clone().Op("!=").Nil()
   194  					} else {
   195  						cond = field.Clone().Op("!=").Lit(zeroValue)
   196  					}
   197  					if named.Optional.ToOptionalType() == OptionalTypeNullable {
   198  						field = jen.Op("*").Add(field)
   199  					}
   200  					code := jen.If(cond).BlockFunc(func(group *jen.Group) {
   201  						switch named.Type.ToMultipartFormDataType() {
   202  						case MultipartFormDataTypeString:
   203  							group.Add(jen.Id("multipartForm").Dot("SetValue").Call(
   204  								jen.Lit(named.Key),
   205  								field,
   206  							))
   207  						case MultipartFormDataTypeInteger:
   208  							group.Add(jen.Id("multipartForm").Dot("SetValue").Call(
   209  								jen.Lit(named.Key),
   210  								jen.Qual("strconv", "FormatInt").Call(field, jen.Lit(10)),
   211  							))
   212  						case MultipartFormDataTypeUploadToken:
   213  							group.Add(
   214  								jen.Id("upToken").
   215  									Op(",").
   216  									Err().
   217  									Op(":=").
   218  									Add(field).
   219  									Dot("GetUpToken").
   220  									Call(jen.Id("ctx")),
   221  							)
   222  							group.Add(
   223  								jen.If(jen.Err().Op("!=").Nil()).
   224  									BlockFunc(func(group *jen.Group) {
   225  										group.Add(jen.Return(jen.Nil(), jen.Err()))
   226  									}),
   227  							)
   228  							group.Add(jen.Id("multipartForm").Dot("SetValue").Call(
   229  								jen.Lit(named.Key),
   230  								jen.Id("upToken"),
   231  							))
   232  						case MultipartFormDataTypeBinaryData:
   233  							group.Add(jen.If(jen.Id("form").Dot(fieldName).Dot("Name").Op("==").Lit("").BlockFunc(func(group *jen.Group) {
   234  								group.Add(jen.Return(
   235  									jen.Nil(),
   236  									jen.Qual(PackageNameErrors, "MissingRequiredFieldError").
   237  										ValuesFunc(func(group *jen.Group) {
   238  											group.Add(jen.Id("Name").Op(":").Lit(fieldName + ".Name"))
   239  										}),
   240  								))
   241  							})))
   242  							group.Add(jen.Id("multipartForm").Dot("SetFile").Call(
   243  								jen.Lit(named.Key),
   244  								jen.Id("form").Dot(fieldName).Dot("Name"),
   245  								jen.Id("form").Dot(fieldName).Dot("ContentType"),
   246  								jen.Id("form").Dot(fieldName).Dot("Data"),
   247  							))
   248  						}
   249  					})
   250  					if named.Optional.ToOptionalType() == OptionalTypeRequired {
   251  						code = code.Else().BlockFunc(func(group *jen.Group) {
   252  							group.Add(jen.Return(
   253  								jen.Nil(),
   254  								jen.Qual(PackageNameErrors, "MissingRequiredFieldError").
   255  									ValuesFunc(func(group *jen.Group) {
   256  										group.Add(jen.Id("Name").Op(":").Lit(fieldName))
   257  									}),
   258  							))
   259  						})
   260  					}
   261  					group.Add(code)
   262  				}
   263  				if free := mff.Free; free != nil {
   264  					group.Add(jen.For(jen.List(jen.Id("key"), jen.Id("value")).Op(":=").Range().Id("form").Dot(free.camelCaseName())).BlockFunc(func(group *jen.Group) {
   265  						group.Add(jen.Id("multipartForm").Dot("SetValue").Call(jen.Id("key"), jen.Id("value")))
   266  					}))
   267  				}
   268  				group.Add(jen.Return(jen.Id("multipartForm"), jen.Nil()))
   269  			}),
   270  	)
   271  	return err
   272  }
   273  
   274  func (mff *MultipartFormFields) getServiceBucketField() *NamedMultipartFormField {
   275  	var serviceBucketField *NamedMultipartFormField
   276  
   277  	for i := range mff.Named {
   278  		if mff.Named[i].ServiceBucket.ToServiceBucketType() != ServiceBucketTypeNone {
   279  			if serviceBucketField == nil {
   280  				serviceBucketField = &mff.Named[i]
   281  			} else {
   282  				panic(fmt.Sprintf("multiple service bucket fields: %s & %s", mff.Named[i].FieldName, serviceBucketField.FieldName))
   283  			}
   284  		}
   285  	}
   286  	return serviceBucketField
   287  }
   288  
   289  func (mff *MultipartFormFields) getServiceObjectField() *NamedMultipartFormField {
   290  	var serviceObjectField *NamedMultipartFormField
   291  
   292  	for i := range mff.Named {
   293  		if mff.Named[i].ServiceObject.ToServiceObjectType() != ServiceObjectTypeNone {
   294  			if serviceObjectField == nil {
   295  				serviceObjectField = &mff.Named[i]
   296  			} else {
   297  				panic(fmt.Sprintf("multiple service object fields: %s & %s", mff.Named[i].FieldName, serviceObjectField.FieldName))
   298  			}
   299  		}
   300  	}
   301  	return serviceObjectField
   302  }