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 }