github.com/qiniu/go-sdk/v7@v7.27.0/internal/api-generator/form.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 FormUrlencodedRequestStruct struct { 12 Fields []FormUrlencodedRequestField `yaml:"fields,omitempty"` 13 } 14 15 FormUrlencodedRequestField struct { 16 FieldName string `yaml:"field_name,omitempty"` 17 FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` 18 FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` 19 Key string `yaml:"key,omitempty"` 20 Documentation string `yaml:"documentation,omitempty"` 21 Type *StringLikeType `yaml:"type,omitempty"` 22 Multiple bool `yaml:"multiple,omitempty"` 23 Optional *OptionalType `yaml:"optional,omitempty"` 24 ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` 25 ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` 26 } 27 ) 28 29 func (field *FormUrlencodedRequestField) camelCaseName() string { 30 if field.FieldCamelCaseName != "" { 31 return field.FieldCamelCaseName 32 } 33 return strcase.ToCamel(field.FieldName) 34 } 35 36 func (form *FormUrlencodedRequestStruct) addFields(group *jen.Group) error { 37 for _, field := range form.Fields { 38 if err := form.generateField(group, field); err != nil { 39 return err 40 } 41 } 42 return nil 43 } 44 45 func (form *FormUrlencodedRequestStruct) addGetBucketNameFunc(group *jen.Group, structName string) (bool, error) { 46 field := form.getServiceBucketField() 47 if field == nil || field.ServiceBucket.ToServiceBucketType() == ServiceBucketTypeNone { 48 return false, nil 49 } else if field.Multiple { 50 panic(fmt.Sprintf("multiple service bucket fields: %s", field.FieldName)) 51 } else if t := field.Type.ToStringLikeType(); t != StringLikeTypeString { 52 panic(fmt.Sprintf("service bucket field must be string: %s", t)) 53 } 54 group.Add(jen.Func(). 55 Params(jen.Id("form").Op("*").Id(structName)). 56 Id("getBucketName"). 57 Params(jen.Id("ctx").Qual("context", "Context")). 58 Params(jen.String(), jen.Error()). 59 BlockFunc(func(group *jen.Group) { 60 fieldName := field.camelCaseName() 61 switch field.ServiceBucket.ToServiceBucketType() { 62 case ServiceBucketTypePlainText: 63 group.Add(jen.Return(jen.Id("form").Dot(fieldName), jen.Nil())) 64 case ServiceBucketTypeEntry: 65 group.Add( 66 jen.Return( 67 jen.Qual("strings", "SplitN"). 68 Call(jen.Id("form").Dot(fieldName), jen.Lit(":"), jen.Lit(2)). 69 Index(jen.Lit(0)), 70 jen.Nil(), 71 ), 72 ) 73 case ServiceBucketTypeUploadToken: 74 group.Add( 75 jen.If(jen.Id("putPolicy"), jen.Err()). 76 Op(":="). 77 Qual(PackageNameUpToken, "NewParser"). 78 Call(jen.Id("form").Dot(fieldName)). 79 Dot("GetPutPolicy"). 80 Call(jen.Id("ctx")). 81 Op(";"). 82 Err(). 83 Op("!="). 84 Nil(). 85 BlockFunc(func(group *jen.Group) { 86 group.Add(jen.Return(jen.Lit(""), jen.Err())) 87 }). 88 Else(). 89 BlockFunc(func(group *jen.Group) { 90 group.Add(jen.Return(jen.Id("putPolicy").Dot("GetBucketName").Call())) 91 }), 92 ) 93 default: 94 panic("unknown ServiceBucketType") 95 } 96 })) 97 return true, nil 98 } 99 100 func (form *FormUrlencodedRequestStruct) addGetObjectNameFunc(group *jen.Group, structName string) (bool, error) { 101 field := form.getServiceObjectField() 102 if field == nil || field.ServiceObject.ToServiceObjectType() == ServiceObjectTypeNone { 103 return false, nil 104 } else if field.Multiple { 105 panic(fmt.Sprintf("multiple service object fields: %s", field.FieldName)) 106 } else if t := field.Type.ToStringLikeType(); t != StringLikeTypeString { 107 panic(fmt.Sprintf("service object field must be string: %s", t)) 108 } 109 group.Add(jen.Func(). 110 Params(jen.Id("form").Op("*").Id(structName)). 111 Id("getObjectName"). 112 Params(). 113 Params(jen.String()). 114 BlockFunc(func(group *jen.Group) { 115 fieldName := field.camelCaseName() 116 switch field.ServiceObject.ToServiceObjectType() { 117 case ServiceObjectTypePlainText: 118 if field.Optional.ToOptionalType() == OptionalTypeNullable { 119 group.Add(jen.Var().Id("objectName").String()) 120 group.Add(jen.If(jen.Id("form").Dot(fieldName).Op("!=").Nil()).BlockFunc(func(group *jen.Group) { 121 group.Add(jen.Id("objectName").Op("=").Op("*").Id("form").Dot(fieldName)) 122 })) 123 group.Add(jen.Return(jen.Id("objectName"))) 124 } else { 125 group.Return(jen.Id("form").Dot(fieldName)) 126 } 127 case ServiceObjectTypeEntry: 128 group.Add( 129 jen.Id("parts"). 130 Op(":="). 131 Qual("strings", "SplitN"). 132 Call(jen.Id("form").Dot(fieldName), jen.Lit(":"), jen.Lit(2))) 133 group.Add(jen.If(jen.Len(jen.Id("parts")).Op(">").Lit(1)), jen.BlockFunc(func(group *jen.Group) { 134 group.Return(jen.Id("parts").Index(jen.Lit(1))) 135 })) 136 group.Add(jen.Return(jen.Lit(""))) 137 default: 138 panic("unknown ServiceObjectType") 139 } 140 })) 141 return true, nil 142 } 143 144 func (form *FormUrlencodedRequestStruct) addBuildFunc(group *jen.Group, structName string) error { 145 var finalErr error = nil 146 group.Add( 147 jen.Func(). 148 Params(jen.Id("form").Op("*").Id(structName)). 149 Id("build"). 150 Params(). 151 Params(jen.Qual("net/url", "Values"), jen.Error()). 152 BlockFunc(func(group *jen.Group) { 153 group.Add(jen.Id("formValues").Op(":=").Make(jen.Qual("net/url", "Values"))) 154 for _, field := range form.Fields { 155 if err := form.addSetCall(group, field, "form", "formValues"); err != nil { 156 finalErr = err 157 return 158 } 159 } 160 group.Add(jen.Return(jen.Id("formValues"), jen.Nil())) 161 }), 162 ) 163 return finalErr 164 } 165 166 func (form *FormUrlencodedRequestStruct) getServiceBucketField() *FormUrlencodedRequestField { 167 var serviceBucketField *FormUrlencodedRequestField 168 169 for i := range form.Fields { 170 if form.Fields[i].ServiceBucket.ToServiceBucketType() != ServiceBucketTypeNone { 171 if serviceBucketField == nil { 172 serviceBucketField = &form.Fields[i] 173 } else { 174 panic(fmt.Sprintf("multiple service bucket fields: %s & %s", form.Fields[i].FieldName, serviceBucketField.FieldName)) 175 } 176 } 177 } 178 return serviceBucketField 179 } 180 181 func (form *FormUrlencodedRequestStruct) getServiceObjectField() *FormUrlencodedRequestField { 182 var serviceObjectField *FormUrlencodedRequestField 183 184 for i := range form.Fields { 185 if form.Fields[i].ServiceObject.ToServiceObjectType() != ServiceBucketTypeNone { 186 if serviceObjectField == nil { 187 serviceObjectField = &form.Fields[i] 188 } else { 189 panic(fmt.Sprintf("multiple service object fields: %s & %s", form.Fields[i].FieldName, serviceObjectField.FieldName)) 190 } 191 } 192 } 193 return serviceObjectField 194 } 195 196 func (form *FormUrlencodedRequestStruct) generateField(group *jen.Group, field FormUrlencodedRequestField) error { 197 code := jen.Id(field.camelCaseName()) 198 if field.Multiple { 199 code = code.Index() 200 } 201 code, err := field.Type.AddTypeToStatement(code, field.Optional.ToOptionalType() == OptionalTypeNullable) 202 if err != nil { 203 return err 204 } 205 if field.Documentation != "" { 206 code = code.Comment(field.Documentation) 207 } 208 group.Add(code) 209 return nil 210 } 211 212 func (form *FormUrlencodedRequestStruct) addSetCall(group *jen.Group, field FormUrlencodedRequestField, formVarName, formValuesVarName string) error { 213 var ( 214 code, valueConvertCode *jen.Statement 215 err error 216 ) 217 fieldName := field.camelCaseName() 218 if field.Multiple { 219 valueConvertCode, err = field.Type.GenerateConvertCodeToString(jen.Id("value")) 220 if err != nil { 221 return err 222 } 223 code = jen.If(jen.Len(jen.Id(formVarName).Dot(fieldName)).Op(">").Lit(0)). 224 BlockFunc(func(group *jen.Group) { 225 group.Add( 226 jen.For(jen.List(jen.Id("_"), jen.Id("value")).Op(":=").Range().Add(jen.Id(formVarName).Dot(fieldName))).BlockFunc(func(group *jen.Group) { 227 group.Add(jen.Id(formValuesVarName).Dot("Add").Call(jen.Lit(field.Key), valueConvertCode)) 228 }), 229 ) 230 }) 231 } else { 232 formField := jen.Id(formVarName).Dot(fieldName) 233 if field.Optional.ToOptionalType() == OptionalTypeNullable { 234 valueConvertCode, err = field.Type.GenerateConvertCodeToString(jen.Op("*").Add(formField)) 235 } else { 236 valueConvertCode, err = field.Type.GenerateConvertCodeToString(formField) 237 } 238 if err != nil { 239 return err 240 } 241 zeroValue, err := field.Type.ZeroValue() 242 if err != nil { 243 return err 244 } 245 condition := formField.Clone() 246 if field.Optional.ToOptionalType() == OptionalTypeNullable { 247 condition = condition.Op("!=").Nil() 248 } else if v, ok := zeroValue.(bool); !ok || v { 249 condition = condition.Op("!=").Lit(zeroValue) 250 } 251 switch field.Optional.ToOptionalType() { 252 case OptionalTypeOmitEmpty, OptionalTypeRequired, OptionalTypeNullable: 253 code = jen.If(condition).BlockFunc(func(group *jen.Group) { 254 group.Add(jen.Id(formValuesVarName).Dot("Set").Call(jen.Lit(field.Key), valueConvertCode)) 255 }) 256 case OptionalTypeKeepEmpty: 257 code = jen.Id(formValuesVarName).Dot("Set").Call(jen.Lit(field.Key), valueConvertCode) 258 } 259 } 260 if field.Optional.ToOptionalType() == OptionalTypeRequired { 261 code = code.Else().BlockFunc(func(group *jen.Group) { 262 group.Add(jen.Return( 263 jen.Nil(), 264 jen.Qual(PackageNameErrors, "MissingRequiredFieldError"). 265 ValuesFunc(func(group *jen.Group) { 266 group.Add(jen.Id("Name").Op(":").Lit(field.camelCaseName())) 267 }), 268 )) 269 }) 270 } 271 group.Add(code) 272 return nil 273 }