decoder.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. // Copyright 2012 The Gorilla Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package schema
  5. import (
  6. "encoding"
  7. "errors"
  8. "fmt"
  9. "mime/multipart"
  10. "reflect"
  11. "strings"
  12. )
  13. const (
  14. defaultMaxSize = 16000
  15. )
  16. // NewDecoder returns a new Decoder.
  17. func NewDecoder() *Decoder {
  18. return &Decoder{cache: newCache(), maxSize: defaultMaxSize}
  19. }
  20. // Decoder decodes values from a map[string][]string to a struct.
  21. type Decoder struct {
  22. cache *cache
  23. zeroEmpty bool
  24. ignoreUnknownKeys bool
  25. maxSize int
  26. }
  27. // SetAliasTag changes the tag used to locate custom field aliases.
  28. // The default tag is "schema".
  29. func (d *Decoder) SetAliasTag(tag string) {
  30. d.cache.tag = tag
  31. }
  32. // ZeroEmpty controls the behaviour when the decoder encounters empty values
  33. // in a map.
  34. // If z is true and a key in the map has the empty string as a value
  35. // then the corresponding struct field is set to the zero value.
  36. // If z is false then empty strings are ignored.
  37. //
  38. // The default value is false, that is empty values do not change
  39. // the value of the struct field.
  40. func (d *Decoder) ZeroEmpty(z bool) {
  41. d.zeroEmpty = z
  42. }
  43. // IgnoreUnknownKeys controls the behaviour when the decoder encounters unknown
  44. // keys in the map.
  45. // If i is true and an unknown field is encountered, it is ignored. This is
  46. // similar to how unknown keys are handled by encoding/json.
  47. // If i is false then Decode will return an error. Note that any valid keys
  48. // will still be decoded in to the target struct.
  49. //
  50. // To preserve backwards compatibility, the default value is false.
  51. func (d *Decoder) IgnoreUnknownKeys(i bool) {
  52. d.ignoreUnknownKeys = i
  53. }
  54. // MaxSize limits the size of slices for URL nested arrays or object arrays.
  55. // Choose MaxSize carefully; large values may create many zero-value slice elements.
  56. // Example: "items.100000=apple" would create a slice with 100,000 empty strings.
  57. func (d *Decoder) MaxSize(size int) {
  58. d.maxSize = size
  59. }
  60. // RegisterConverter registers a converter function for a custom type.
  61. func (d *Decoder) RegisterConverter(value interface{}, converterFunc Converter) {
  62. d.cache.registerConverter(value, converterFunc)
  63. }
  64. // Decode decodes a map[string][]string to a struct.
  65. //
  66. // The first parameter must be a pointer to a struct.
  67. //
  68. // The second parameter is a map, typically url.Values from an HTTP request.
  69. // Keys are "paths" in dotted notation to the struct fields and nested structs.
  70. //
  71. // See the package documentation for a full explanation of the mechanics.
  72. func (d *Decoder) Decode(dst interface{}, src map[string][]string, files ...map[string][]*multipart.FileHeader) (err error) {
  73. var multipartFiles map[string][]*multipart.FileHeader
  74. if len(files) > 0 {
  75. multipartFiles = files[0]
  76. }
  77. // Add files as empty string values to src in order to make path parsing work easily
  78. for path := range multipartFiles {
  79. src[path] = []string{""}
  80. }
  81. v := reflect.ValueOf(dst)
  82. if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
  83. return errors.New("schema: interface must be a pointer to struct")
  84. }
  85. // Catch panics from the decoder and return them as an error.
  86. // This is needed because the decoder calls reflect and reflect panics
  87. defer func() {
  88. if r := recover(); r != nil {
  89. if e, ok := r.(error); ok {
  90. err = e
  91. } else {
  92. err = fmt.Errorf("schema: panic while decoding: %v", r)
  93. }
  94. }
  95. }()
  96. v = v.Elem()
  97. t := v.Type()
  98. multiErrors := MultiError{}
  99. for path, values := range src {
  100. if parts, err := d.cache.parsePath(path, t); err == nil {
  101. if filesSlice, ok := multipartFiles[path]; ok {
  102. if err = d.decode(v, path, parts, values, filesSlice); err != nil {
  103. multiErrors[path] = err
  104. }
  105. } else {
  106. if err = d.decode(v, path, parts, values, nil); err != nil {
  107. multiErrors[path] = err
  108. }
  109. }
  110. } else {
  111. if errors.Is(err, errIndexTooLarge) {
  112. multiErrors[path] = err
  113. } else if !d.ignoreUnknownKeys {
  114. multiErrors[path] = UnknownKeyError{Key: path}
  115. }
  116. }
  117. }
  118. multiErrors.merge(d.setDefaults(t, v, src, ""))
  119. multiErrors.merge(d.checkRequired(t, src))
  120. if len(multiErrors) > 0 {
  121. return multiErrors
  122. }
  123. return nil
  124. }
  125. // setDefaults sets the default values when the `default` tag is specified,
  126. // default is supported on basic/primitive types and their pointers,
  127. // nested structs can also have default tags
  128. func (d *Decoder) setDefaults(t reflect.Type, v reflect.Value, src map[string][]string, prefix string) MultiError {
  129. struc := d.cache.get(t)
  130. if struc == nil {
  131. // unexpect, cache.get never return nil
  132. return MultiError{"default-" + t.Name(): errors.New("cache fail")}
  133. }
  134. errs := MultiError{}
  135. if v.Type().Kind() == reflect.Struct {
  136. for i := 0; i < v.NumField(); i++ {
  137. field := v.Field(i)
  138. if field.Type().Kind() == reflect.Ptr && field.IsNil() && v.Type().Field(i).Anonymous {
  139. field.Set(reflect.New(field.Type().Elem()))
  140. }
  141. }
  142. }
  143. for _, f := range struc.fields {
  144. vCurrent := v.FieldByName(f.name)
  145. if vCurrent.Type().Kind() == reflect.Struct && f.defaultValue == "" {
  146. errs.merge(d.setDefaults(vCurrent.Type(), vCurrent, src, prefix+f.canonicalAlias+"."))
  147. } else if isPointerToStruct(vCurrent) && f.defaultValue == "" {
  148. errs.merge(d.setDefaults(vCurrent.Elem().Type(), vCurrent.Elem(), src, prefix+f.canonicalAlias+"."))
  149. }
  150. if f.defaultValue != "" && f.isRequired {
  151. errs.merge(MultiError{"default-" + f.name: errors.New("required fields cannot have a default value")})
  152. } else if f.defaultValue != "" && vCurrent.IsZero() && !f.isRequired && !fieldProvided(src, prefix, f) {
  153. if f.typ.Kind() == reflect.Struct {
  154. errs.merge(MultiError{"default-" + f.name: errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")})
  155. } else if f.typ.Kind() == reflect.Slice {
  156. vals := strings.Split(f.defaultValue, "|")
  157. // check if slice has one of the supported types for defaults
  158. if _, ok := builtinConverters[f.typ.Elem().Kind()]; !ok {
  159. errs.merge(MultiError{"default-" + f.name: errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")})
  160. continue
  161. }
  162. defaultSlice := reflect.MakeSlice(f.typ, 0, cap(vals))
  163. for _, val := range vals {
  164. // this check is to handle if the wrong value is provided
  165. convertedVal := builtinConverters[f.typ.Elem().Kind()](val)
  166. if !convertedVal.IsValid() {
  167. errs.merge(MultiError{"default-" + f.name: fmt.Errorf("failed setting default: %s is not compatible with field %s type", val, f.name)})
  168. break
  169. }
  170. defaultSlice = reflect.Append(defaultSlice, convertedVal)
  171. }
  172. vCurrent.Set(defaultSlice)
  173. } else if f.typ.Kind() == reflect.Ptr {
  174. t1 := f.typ.Elem()
  175. if t1.Kind() == reflect.Struct || t1.Kind() == reflect.Slice {
  176. errs.merge(MultiError{"default-" + f.name: errors.New("default option is supported only on: bool, float variants, string, unit variants types or their corresponding pointers or slices")})
  177. }
  178. // this check is to handle if the wrong value is provided
  179. if convertedVal := convertPointer(t1.Kind(), f.defaultValue); convertedVal.IsValid() {
  180. vCurrent.Set(convertedVal)
  181. }
  182. } else {
  183. // this check is to handle if the wrong value is provided
  184. if convertedVal := builtinConverters[f.typ.Kind()](f.defaultValue); convertedVal.IsValid() {
  185. vCurrent.Set(builtinConverters[f.typ.Kind()](f.defaultValue))
  186. }
  187. }
  188. }
  189. }
  190. return errs
  191. }
  192. func isPointerToStruct(v reflect.Value) bool {
  193. return !v.IsZero() && v.Type().Kind() == reflect.Ptr && v.Elem().Type().Kind() == reflect.Struct
  194. }
  195. func fieldProvided(src map[string][]string, prefix string, f *fieldInfo) bool {
  196. for _, p := range f.paths(prefix) {
  197. if _, ok := src[p]; ok {
  198. return true
  199. }
  200. }
  201. return false
  202. }
  203. // checkRequired checks whether required fields are empty
  204. //
  205. // check type t recursively if t has struct fields.
  206. //
  207. // src is the source map for decoding, we use it here to see if those required fields are included in src
  208. func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string) MultiError {
  209. m, errs := d.findRequiredFields(t, "", "")
  210. for key, fields := range m {
  211. if isEmptyFields(fields, src) {
  212. errs[key] = EmptyFieldError{Key: key}
  213. }
  214. }
  215. return errs
  216. }
  217. // findRequiredFields recursively searches the struct type t for required fields.
  218. //
  219. // canonicalPrefix and searchPrefix are used to resolve full paths in dotted notation
  220. // for nested struct fields. canonicalPrefix is a complete path which never omits
  221. // any embedded struct fields. searchPrefix is a user-friendly path which may omit
  222. // some embedded struct fields to point promoted fields.
  223. func (d *Decoder) findRequiredFields(t reflect.Type, canonicalPrefix, searchPrefix string) (map[string][]fieldWithPrefix, MultiError) {
  224. struc := d.cache.get(t)
  225. if struc == nil {
  226. // unexpect, cache.get never return nil
  227. return nil, MultiError{canonicalPrefix + "*": errors.New("cache fail")}
  228. }
  229. m := map[string][]fieldWithPrefix{}
  230. errs := MultiError{}
  231. for _, f := range struc.fields {
  232. if f.typ.Kind() == reflect.Struct {
  233. fcprefix := canonicalPrefix + f.canonicalAlias + "."
  234. for _, fspath := range f.paths(searchPrefix) {
  235. fm, ferrs := d.findRequiredFields(f.typ, fcprefix, fspath+".")
  236. for key, fields := range fm {
  237. m[key] = append(m[key], fields...)
  238. }
  239. errs.merge(ferrs)
  240. }
  241. }
  242. if f.isRequired {
  243. key := canonicalPrefix + f.canonicalAlias
  244. m[key] = append(m[key], fieldWithPrefix{
  245. fieldInfo: f,
  246. prefix: searchPrefix,
  247. })
  248. }
  249. }
  250. return m, errs
  251. }
  252. type fieldWithPrefix struct {
  253. *fieldInfo
  254. prefix string
  255. }
  256. // isEmptyFields returns true if all of specified fields are empty.
  257. func isEmptyFields(fields []fieldWithPrefix, src map[string][]string) bool {
  258. for _, f := range fields {
  259. for _, path := range f.paths(f.prefix) {
  260. v, ok := src[path]
  261. if ok && !isEmpty(f.typ, v) {
  262. return false
  263. }
  264. for key := range src {
  265. nested := strings.IndexByte(key, '.') != -1
  266. // for non required nested structs
  267. c1 := strings.HasSuffix(f.prefix, ".") && key == path
  268. // for required nested structs
  269. c2 := f.prefix == "" && nested && strings.HasPrefix(key, path)
  270. // for non nested fields
  271. c3 := f.prefix == "" && !nested && key == path
  272. if !isEmpty(f.typ, src[key]) && (c1 || c2 || c3) {
  273. return false
  274. }
  275. }
  276. }
  277. }
  278. return true
  279. }
  280. // isEmpty returns true if value is empty for specific type
  281. func isEmpty(t reflect.Type, value []string) bool {
  282. if len(value) == 0 {
  283. return true
  284. }
  285. switch t.Kind() {
  286. case boolType, float32Type, float64Type, intType, int8Type, int32Type, int64Type, stringType, uint8Type, uint16Type, uint32Type, uint64Type:
  287. return len(value[0]) == 0
  288. }
  289. return false
  290. }
  291. var (
  292. multipartFileHeaderPointerType = reflect.TypeOf(&multipart.FileHeader{})
  293. sliceMultipartFileHeaderPointerType = reflect.TypeOf([]*multipart.FileHeader{})
  294. )
  295. // Supported multiple types:
  296. // *multipart.FileHeader, *[]multipart.FileHeader, []*multipart.FileHeader
  297. func handleMultipartField(field reflect.Value, files []*multipart.FileHeader) bool {
  298. fieldType := field.Type()
  299. if !isMultipartField(fieldType) {
  300. return false
  301. }
  302. // Skip if files are empty and field is multipart
  303. if len(files) == 0 {
  304. return true
  305. }
  306. // Check for *multipart.FileHeader
  307. if fieldType == multipartFileHeaderPointerType {
  308. field.Set(reflect.ValueOf(files[0]))
  309. return true
  310. }
  311. // Check for []*multipart.FileHeader
  312. if fieldType == sliceMultipartFileHeaderPointerType {
  313. field.Set(reflect.ValueOf(files))
  314. return true
  315. }
  316. // Check for *[]*multipart.FileHeader
  317. if fieldType.Kind() == reflect.Pointer {
  318. fieldType = fieldType.Elem()
  319. if field.IsNil() {
  320. field.Set(reflect.New(fieldType))
  321. }
  322. if fieldType == sliceMultipartFileHeaderPointerType {
  323. field.Elem().Set(reflect.ValueOf(files))
  324. return true
  325. }
  326. }
  327. return false
  328. }
  329. // Supported multiple types:
  330. // *multipart.FileHeader, *[]multipart.FileHeader, []*multipart.FileHeader
  331. func isMultipartField(typ reflect.Type) bool {
  332. // Check for *multipart.FileHeader
  333. if typ == multipartFileHeaderPointerType {
  334. return true
  335. }
  336. // Check for []*multipart.FileHeader
  337. if typ == sliceMultipartFileHeaderPointerType {
  338. return true
  339. }
  340. // Check for *[]*multipart.FileHeader
  341. if typ.Kind() == reflect.Ptr {
  342. typ = typ.Elem()
  343. if typ == sliceMultipartFileHeaderPointerType {
  344. return true
  345. }
  346. }
  347. return false
  348. }
  349. // decode fills a struct field using a parsed path.
  350. func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values []string, files []*multipart.FileHeader) error {
  351. // Get the field walking the struct fields by index.
  352. for _, name := range parts[0].path {
  353. if v.Type().Kind() == reflect.Ptr {
  354. if v.IsNil() {
  355. v.Set(reflect.New(v.Type().Elem()))
  356. }
  357. v = v.Elem()
  358. }
  359. // Allocate embedded anonymous pointers required for promoted fields.
  360. if v.Type().Kind() == reflect.Struct {
  361. d.ensureAnonymousPtrs(v)
  362. }
  363. v = v.FieldByName(name)
  364. }
  365. // Don't even bother for unexported fields.
  366. if !v.CanSet() {
  367. return nil
  368. }
  369. // Check multipart files
  370. if mp := handleMultipartField(v, files); mp {
  371. return nil
  372. }
  373. // Dereference if needed.
  374. t := v.Type()
  375. if t.Kind() == reflect.Ptr {
  376. t = t.Elem()
  377. if v.IsNil() {
  378. v.Set(reflect.New(t))
  379. }
  380. v = v.Elem()
  381. }
  382. // Slice of structs. Let's go recursive.
  383. if len(parts) > 1 {
  384. idx := parts[0].index
  385. // a defensive check to avoid creating a large slice based on user input index
  386. if idx > d.maxSize {
  387. return fmt.Errorf("%v index %d is larger than the configured maxSize %d", v.Kind(), idx, d.maxSize)
  388. }
  389. if v.IsNil() || v.Len() < idx+1 {
  390. value := reflect.MakeSlice(t, idx+1, idx+1)
  391. if v.Len() < idx+1 {
  392. // Resize it.
  393. reflect.Copy(value, v)
  394. }
  395. v.Set(value)
  396. }
  397. return d.decode(v.Index(idx), path, parts[1:], values, files)
  398. }
  399. // Get the converter early in case there is one for a slice type.
  400. conv := d.cache.converter(t)
  401. m := isTextUnmarshaler(v)
  402. if conv == nil && t.Kind() == reflect.Slice && m.IsSliceElement {
  403. var items []reflect.Value
  404. elemT := t.Elem()
  405. isPtrElem := elemT.Kind() == reflect.Ptr
  406. if isPtrElem {
  407. elemT = elemT.Elem()
  408. }
  409. // Try to get a converter for the element type.
  410. conv := d.cache.converter(elemT)
  411. if conv == nil {
  412. conv = builtinConverters[elemT.Kind()]
  413. if conv == nil {
  414. // As we are not dealing with slice of structs here, we don't need to check if the type
  415. // implements TextUnmarshaler interface
  416. return fmt.Errorf("schema: converter not found for %v", elemT)
  417. }
  418. }
  419. for key, value := range values {
  420. if value == "" {
  421. if d.zeroEmpty {
  422. items = append(items, reflect.Zero(elemT))
  423. }
  424. } else if m.IsValid {
  425. u := reflect.New(elemT)
  426. if m.IsSliceElementPtr {
  427. u = reflect.New(reflect.PointerTo(elemT).Elem())
  428. }
  429. um, _ := reflect.TypeAssert[encoding.TextUnmarshaler](u)
  430. if err := um.UnmarshalText([]byte(value)); err != nil {
  431. return ConversionError{
  432. Key: path,
  433. Type: t,
  434. Index: key,
  435. Err: err,
  436. }
  437. }
  438. if m.IsSliceElementPtr {
  439. items = append(items, u.Elem().Addr())
  440. } else if u.Kind() == reflect.Ptr {
  441. items = append(items, u.Elem())
  442. } else {
  443. items = append(items, u)
  444. }
  445. } else if item := conv(value); item.IsValid() {
  446. if isPtrElem {
  447. ptr := reflect.New(elemT)
  448. ptr.Elem().Set(item)
  449. item = ptr
  450. }
  451. if item.Type() != elemT && !isPtrElem {
  452. item = item.Convert(elemT)
  453. }
  454. items = append(items, item)
  455. } else {
  456. if strings.Contains(value, ",") {
  457. values := strings.Split(value, ",")
  458. for _, value := range values {
  459. if value == "" {
  460. if d.zeroEmpty {
  461. items = append(items, reflect.Zero(elemT))
  462. }
  463. } else if item := conv(value); item.IsValid() {
  464. if isPtrElem {
  465. ptr := reflect.New(elemT)
  466. ptr.Elem().Set(item)
  467. item = ptr
  468. }
  469. if item.Type() != elemT && !isPtrElem {
  470. item = item.Convert(elemT)
  471. }
  472. items = append(items, item)
  473. } else {
  474. return ConversionError{
  475. Key: path,
  476. Type: elemT,
  477. Index: key,
  478. }
  479. }
  480. }
  481. } else {
  482. return ConversionError{
  483. Key: path,
  484. Type: elemT,
  485. Index: key,
  486. }
  487. }
  488. }
  489. }
  490. value := reflect.Append(reflect.MakeSlice(t, 0, 0), items...)
  491. v.Set(value)
  492. } else {
  493. val := ""
  494. // Use the last value provided if any values were provided
  495. if len(values) > 0 {
  496. val = values[len(values)-1]
  497. }
  498. if conv != nil {
  499. if value := conv(val); value.IsValid() {
  500. v.Set(value.Convert(t))
  501. } else {
  502. return ConversionError{
  503. Key: path,
  504. Type: t,
  505. Index: -1,
  506. }
  507. }
  508. } else if m.IsValid {
  509. if m.IsPtr {
  510. u := reflect.New(v.Type())
  511. um, _ := reflect.TypeAssert[encoding.TextUnmarshaler](u)
  512. if err := um.UnmarshalText([]byte(val)); err != nil {
  513. return ConversionError{
  514. Key: path,
  515. Type: t,
  516. Index: -1,
  517. Err: err,
  518. }
  519. }
  520. v.Set(reflect.Indirect(u))
  521. } else {
  522. // If the value implements the encoding.TextUnmarshaler interface
  523. // apply UnmarshalText as the converter
  524. if err := m.Unmarshaler.UnmarshalText([]byte(val)); err != nil {
  525. return ConversionError{
  526. Key: path,
  527. Type: t,
  528. Index: -1,
  529. Err: err,
  530. }
  531. }
  532. }
  533. } else if val == "" {
  534. if d.zeroEmpty {
  535. v.Set(reflect.Zero(t))
  536. }
  537. } else if conv := builtinConverters[t.Kind()]; conv != nil {
  538. if value := conv(val); value.IsValid() {
  539. v.Set(value.Convert(t))
  540. } else {
  541. return ConversionError{
  542. Key: path,
  543. Type: t,
  544. Index: -1,
  545. }
  546. }
  547. } else {
  548. return fmt.Errorf("schema: converter not found for %v", t)
  549. }
  550. }
  551. return nil
  552. }
  553. func (d *Decoder) ensureAnonymousPtrs(v reflect.Value) {
  554. info := d.cache.get(v.Type())
  555. for _, idx := range info.anonymousPtrFields {
  556. field := v.Field(idx)
  557. if field.IsNil() {
  558. field.Set(reflect.New(field.Type().Elem()))
  559. }
  560. }
  561. }
  562. func isTextUnmarshaler(v reflect.Value) unmarshaler {
  563. // Create a new unmarshaller instance
  564. m := unmarshaler{}
  565. if m.Unmarshaler, m.IsValid = reflect.TypeAssert[encoding.TextUnmarshaler](v); m.IsValid {
  566. return m
  567. }
  568. // As the UnmarshalText function should be applied to the pointer of the
  569. // type, we check that type to see if it implements the necessary
  570. // method.
  571. if m.Unmarshaler, m.IsValid = reflect.TypeAssert[encoding.TextUnmarshaler](reflect.New(v.Type())); m.IsValid {
  572. m.IsPtr = true
  573. return m
  574. }
  575. // if v is []T or *[]T create new T
  576. t := v.Type()
  577. if t.Kind() == reflect.Ptr {
  578. t = t.Elem()
  579. }
  580. if t.Kind() == reflect.Slice {
  581. // Check if the slice implements encoding.TextUnmarshaller
  582. if m.Unmarshaler, m.IsValid = reflect.TypeAssert[encoding.TextUnmarshaler](v); m.IsValid {
  583. return m
  584. }
  585. // If t is a pointer slice, check if its elements implement
  586. // encoding.TextUnmarshaler
  587. m.IsSliceElement = true
  588. if t = t.Elem(); t.Kind() == reflect.Ptr {
  589. t = reflect.PointerTo(t.Elem())
  590. v = reflect.Zero(t)
  591. m.IsSliceElementPtr = true
  592. m.Unmarshaler, m.IsValid = reflect.TypeAssert[encoding.TextUnmarshaler](v)
  593. return m
  594. }
  595. }
  596. v = reflect.New(t)
  597. m.Unmarshaler, m.IsValid = reflect.TypeAssert[encoding.TextUnmarshaler](v)
  598. return m
  599. }
  600. // TextUnmarshaler helpers ----------------------------------------------------
  601. // unmarshaller contains information about a TextUnmarshaler type
  602. type unmarshaler struct {
  603. Unmarshaler encoding.TextUnmarshaler
  604. // IsValid indicates whether the resolved type indicated by the other
  605. // flags implements the encoding.TextUnmarshaler interface.
  606. IsValid bool
  607. // IsPtr indicates that the resolved type is the pointer of the original
  608. // type.
  609. IsPtr bool
  610. // IsSliceElement indicates that the resolved type is a slice element of
  611. // the original type.
  612. IsSliceElement bool
  613. // IsSliceElementPtr indicates that the resolved type is a pointer to a
  614. // slice element of the original type.
  615. IsSliceElementPtr bool
  616. }
  617. // Errors ---------------------------------------------------------------------
  618. // ConversionError stores information about a failed conversion.
  619. type ConversionError struct {
  620. Key string // key from the source map.
  621. Type reflect.Type // expected type of elem
  622. Index int // index for multi-value fields; -1 for single-value fields.
  623. Err error // low-level error (when it exists)
  624. }
  625. func (e ConversionError) Error() string {
  626. var output string
  627. if e.Index < 0 {
  628. output = fmt.Sprintf("schema: error converting value for %q", e.Key)
  629. } else {
  630. output = fmt.Sprintf("schema: error converting value for index %d of %q",
  631. e.Index, e.Key)
  632. }
  633. if e.Err != nil {
  634. output = fmt.Sprintf("%s. Details: %s", output, e.Err)
  635. }
  636. return output
  637. }
  638. // UnknownKeyError stores information about an unknown key in the source map.
  639. type UnknownKeyError struct {
  640. Key string // key from the source map.
  641. }
  642. func (e UnknownKeyError) Error() string {
  643. return fmt.Sprintf("schema: invalid path %q", e.Key)
  644. }
  645. // EmptyFieldError stores information about an empty required field.
  646. type EmptyFieldError struct {
  647. Key string // required key in the source map.
  648. }
  649. func (e EmptyFieldError) Error() string {
  650. return fmt.Sprintf("%v is empty", e.Key)
  651. }
  652. // MultiError stores multiple decoding errors.
  653. //
  654. // Borrowed from the App Engine SDK.
  655. type MultiError map[string]error
  656. func (e MultiError) Error() string {
  657. s := ""
  658. for _, err := range e {
  659. s = err.Error()
  660. break
  661. }
  662. switch len(e) {
  663. case 0:
  664. return "(0 errors)"
  665. case 1:
  666. return s
  667. case 2:
  668. return s + " (and 1 other error)"
  669. }
  670. return fmt.Sprintf("%s (and %d other errors)", s, len(e)-1)
  671. }
  672. func (e MultiError) merge(errors MultiError) {
  673. for key, err := range errors {
  674. if e[key] == nil {
  675. e[key] = err
  676. }
  677. }
  678. }