conf.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. package goconf
  2. import (
  3. "bufio"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "os"
  8. "reflect"
  9. "strconv"
  10. "strings"
  11. "time"
  12. )
  13. const (
  14. // formatter
  15. CRLF = '\n'
  16. Comment = "#"
  17. Spliter = " "
  18. SectionS = "["
  19. SectionE = "]"
  20. // memory unit
  21. Byte = 1
  22. KB = 1024 * Byte
  23. MB = 1024 * KB
  24. GB = 1024 * MB
  25. )
  26. // Section is the key-value data object.
  27. type Section struct {
  28. data map[string]string // key:value
  29. dataOrder []string
  30. dataComments map[string][]string // key:comments
  31. Name string
  32. comments []string
  33. Comment string
  34. }
  35. // Config is the key-value configuration object.
  36. type Config struct {
  37. data map[string]*Section
  38. dataOrder []string
  39. file string
  40. Comment string
  41. Spliter string
  42. }
  43. // New return a new default Config object (Comment = '#', spliter = ' ').
  44. func New() *Config {
  45. return &Config{Comment: Comment, Spliter: Spliter, data: map[string]*Section{}}
  46. }
  47. // ParseReader parse config file by a io.Reader.
  48. func (c *Config) ParseReader(reader io.Reader) error {
  49. var (
  50. err error
  51. line int
  52. idx int
  53. row string
  54. key string
  55. value string
  56. comments []string
  57. section *Section
  58. rd = bufio.NewReader(reader)
  59. )
  60. for {
  61. line++
  62. row, err = rd.ReadString(CRLF)
  63. if err == io.EOF && len(row) == 0 {
  64. // file end
  65. break
  66. } else if err != nil && err != io.EOF {
  67. return err
  68. }
  69. row = strings.TrimSpace(row)
  70. // ignore blank line
  71. // ignore Comment line
  72. if len(row) == 0 || strings.HasPrefix(row, c.Comment) {
  73. comments = append(comments, row)
  74. continue
  75. }
  76. // get secion
  77. if strings.HasPrefix(row, SectionS) {
  78. if !strings.HasSuffix(row, SectionE) {
  79. return errors.New(fmt.Sprintf("no end section: %s at :%d", SectionE, line))
  80. }
  81. sectionStr := row[1 : len(row)-1]
  82. // store the section
  83. s, ok := c.data[sectionStr]
  84. if !ok {
  85. s = &Section{data: map[string]string{}, dataComments: map[string][]string{}, comments: comments, Comment: c.Comment, Name: sectionStr}
  86. c.data[sectionStr] = s
  87. c.dataOrder = append(c.dataOrder, sectionStr)
  88. } else {
  89. return errors.New(fmt.Sprintf("section: %s already exists at %d", sectionStr, line))
  90. }
  91. section = s
  92. comments = []string{}
  93. continue
  94. }
  95. // get the spliter index
  96. idx = strings.Index(row, c.Spliter)
  97. if idx > 0 {
  98. // get the key and value
  99. key = strings.TrimSpace(row[:idx])
  100. if len(row) > idx {
  101. value = strings.TrimSpace(row[idx+1:])
  102. }
  103. } else {
  104. return errors.New(fmt.Sprintf("no spliter in key: %s at %d", row, line))
  105. }
  106. // check section exists
  107. if section == nil {
  108. return errors.New(fmt.Sprintf("no section for key: %s at %d", key, line))
  109. }
  110. // check key already exists
  111. if _, ok := section.data[key]; ok {
  112. return errors.New(fmt.Sprintf("section: %s already has key: %s at %d", section.Name, key, line))
  113. }
  114. // save key-value
  115. section.data[key] = value
  116. // save comments for key
  117. section.dataComments[key] = comments
  118. section.dataOrder = append(section.dataOrder, key)
  119. // clean comments
  120. comments = []string{}
  121. }
  122. return nil
  123. }
  124. // Parse parse the specified config file.
  125. func (c *Config) Parse(file string) error {
  126. // open config file
  127. if f, err := os.Open(file); err != nil {
  128. return err
  129. } else {
  130. defer f.Close()
  131. c.file = file
  132. return c.ParseReader(f)
  133. }
  134. }
  135. // Get get a config section by key.
  136. func (c *Config) Get(section string) *Section {
  137. s, _ := c.data[section]
  138. return s
  139. }
  140. // Add add a new config section, if exist the section key then return the existing one.
  141. func (c *Config) Add(section string, comments ...string) *Section {
  142. s, ok := c.data[section]
  143. if !ok {
  144. var dataComments []string
  145. for _, comment := range comments {
  146. for _, line := range strings.Split(comment, string(CRLF)) {
  147. dataComments = append(dataComments, fmt.Sprintf("%s%s", c.Comment, line))
  148. }
  149. }
  150. s = &Section{data: map[string]string{}, Name: section, comments: dataComments, Comment: c.Comment, dataComments: map[string][]string{}}
  151. c.data[section] = s
  152. c.dataOrder = append(c.dataOrder, section)
  153. }
  154. return s
  155. }
  156. // Remove remove the specified section.
  157. func (c *Config) Remove(section string) {
  158. if _, ok := c.data[section]; ok {
  159. for i, k := range c.dataOrder {
  160. if k == section {
  161. c.dataOrder = append(c.dataOrder[:i], c.dataOrder[i+1:]...)
  162. break
  163. }
  164. }
  165. delete(c.data, section)
  166. }
  167. }
  168. // Sections return all the config sections.
  169. func (c *Config) Sections() []string {
  170. // safe-copy
  171. sections := []string{}
  172. for _, k := range c.dataOrder {
  173. sections = append(sections, k)
  174. }
  175. return sections
  176. }
  177. // Save save current configuration to specified file, if file is "" then rewrite the original file.
  178. func (c *Config) Save(file string) error {
  179. if file == "" {
  180. file = c.file
  181. } else {
  182. c.file = file
  183. }
  184. // save core file
  185. return c.saveFile(file)
  186. }
  187. // saveFile save config info in specified file.
  188. func (c *Config) saveFile(file string) error {
  189. f, err := os.OpenFile(file, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
  190. if err != nil {
  191. return err
  192. }
  193. defer f.Close()
  194. // sections
  195. for _, section := range c.dataOrder {
  196. data, _ := c.data[section]
  197. // comments
  198. for _, comment := range data.comments {
  199. if _, err := f.WriteString(fmt.Sprintf("%s%c", comment, CRLF)); err != nil {
  200. return err
  201. }
  202. }
  203. // section
  204. if _, err := f.WriteString(fmt.Sprintf("[%s]%c", section, CRLF)); err != nil {
  205. return err
  206. }
  207. // key-values
  208. for _, k := range data.dataOrder {
  209. v, _ := data.data[k]
  210. // comments
  211. for _, comment := range data.dataComments[k] {
  212. if _, err := f.WriteString(fmt.Sprintf("%s%c", comment, CRLF)); err != nil {
  213. return err
  214. }
  215. }
  216. // key-value
  217. if _, err := f.WriteString(fmt.Sprintf("%s%s%s%c", k, c.Spliter, v, CRLF)); err != nil {
  218. return err
  219. }
  220. }
  221. }
  222. return nil
  223. }
  224. // Reload reload the config file and return a new Config.
  225. func (c *Config) Reload() (*Config, error) {
  226. nc := &Config{Comment: c.Comment, Spliter: c.Spliter, file: c.file, data: map[string]*Section{}}
  227. if err := nc.Parse(c.file); err != nil {
  228. return nil, err
  229. }
  230. return nc, nil
  231. }
  232. // Add add a new key-value configuration for the section.
  233. func (s *Section) Add(k, v string, comments ...string) {
  234. if _, ok := s.data[k]; !ok {
  235. s.dataOrder = append(s.dataOrder, k)
  236. for _, comment := range comments {
  237. for _, line := range strings.Split(comment, string(CRLF)) {
  238. s.dataComments[k] = append(s.dataComments[k], fmt.Sprintf("%s%s", s.Comment, line))
  239. }
  240. }
  241. }
  242. s.data[k] = v
  243. }
  244. // Remove remove the specified key configuration for the section.
  245. func (s *Section) Remove(k string) {
  246. delete(s.data, k)
  247. for i, key := range s.dataOrder {
  248. if key == k {
  249. s.dataOrder = append(s.dataOrder[:i], s.dataOrder[i+1:]...)
  250. break
  251. }
  252. }
  253. }
  254. // An NoKeyError describes a goconf key that was not found in the section.
  255. type NoKeyError struct {
  256. Key string
  257. Section string
  258. }
  259. func (e *NoKeyError) Error() string {
  260. return fmt.Sprintf("key: \"%s\" not found in [%s]", e.Key, e.Section)
  261. }
  262. // String get config string value.
  263. func (s *Section) String(key string) (string, error) {
  264. if v, ok := s.data[key]; ok {
  265. return v, nil
  266. } else {
  267. return "", &NoKeyError{Key: key, Section: s.Name}
  268. }
  269. }
  270. // Strings get config []string value.
  271. func (s *Section) Strings(key, delim string) ([]string, error) {
  272. if v, ok := s.data[key]; ok {
  273. return strings.Split(v, delim), nil
  274. } else {
  275. return nil, &NoKeyError{Key: key, Section: s.Name}
  276. }
  277. }
  278. // Int get config int value.
  279. func (s *Section) Int(key string) (int64, error) {
  280. if v, ok := s.data[key]; ok {
  281. return strconv.ParseInt(v, 10, 64)
  282. } else {
  283. return 0, &NoKeyError{Key: key, Section: s.Name}
  284. }
  285. }
  286. // Uint get config uint value.
  287. func (s *Section) Uint(key string) (uint64, error) {
  288. if v, ok := s.data[key]; ok {
  289. return strconv.ParseUint(v, 10, 64)
  290. } else {
  291. return 0, &NoKeyError{Key: key, Section: s.Name}
  292. }
  293. }
  294. // Float get config float value.
  295. func (s *Section) Float(key string) (float64, error) {
  296. if v, ok := s.data[key]; ok {
  297. return strconv.ParseFloat(v, 64)
  298. } else {
  299. return 0, &NoKeyError{Key: key, Section: s.Name}
  300. }
  301. }
  302. // Bool get config boolean value.
  303. //
  304. // "yes", "1", "y", "true", "enable" means true.
  305. //
  306. // "no", "0", "n", "false", "disable" means false.
  307. //
  308. // if the specified value unknown then return false.
  309. func (s *Section) Bool(key string) (bool, error) {
  310. if v, ok := s.data[key]; ok {
  311. v = strings.ToLower(v)
  312. return parseBool(v), nil
  313. } else {
  314. return false, &NoKeyError{Key: key, Section: s.Name}
  315. }
  316. }
  317. func parseBool(v string) bool {
  318. if v == "true" || v == "yes" || v == "1" || v == "y" || v == "enable" {
  319. return true
  320. } else if v == "false" || v == "no" || v == "0" || v == "n" || v == "disable" {
  321. return false
  322. } else {
  323. return false
  324. }
  325. }
  326. // Byte get config byte number value.
  327. //
  328. // 1kb = 1k = 1024.
  329. //
  330. // 1mb = 1m = 1024 * 1024.
  331. //
  332. // 1gb = 1g = 1024 * 1024 * 1024.
  333. func (s *Section) MemSize(key string) (int, error) {
  334. if v, ok := s.data[key]; ok {
  335. return parseMemory(v)
  336. } else {
  337. return 0, &NoKeyError{Key: key, Section: s.Name}
  338. }
  339. }
  340. func parseMemory(v string) (int, error) {
  341. unit := Byte
  342. subIdx := len(v)
  343. if strings.HasSuffix(v, "k") {
  344. unit = KB
  345. subIdx = subIdx - 1
  346. } else if strings.HasSuffix(v, "kb") {
  347. unit = KB
  348. subIdx = subIdx - 2
  349. } else if strings.HasSuffix(v, "m") {
  350. unit = MB
  351. subIdx = subIdx - 1
  352. } else if strings.HasSuffix(v, "mb") {
  353. unit = MB
  354. subIdx = subIdx - 2
  355. } else if strings.HasSuffix(v, "g") {
  356. unit = GB
  357. subIdx = subIdx - 1
  358. } else if strings.HasSuffix(v, "gb") {
  359. unit = GB
  360. subIdx = subIdx - 2
  361. }
  362. b, err := strconv.ParseInt(v[:subIdx], 10, 64)
  363. if err != nil {
  364. return 0, err
  365. }
  366. return int(b) * unit, nil
  367. }
  368. // Duration get config second value.
  369. //
  370. // 1s = 1sec = 1.
  371. //
  372. // 1m = 1min = 60.
  373. //
  374. // 1h = 1hour = 60 * 60.
  375. func (s *Section) Duration(key string) (time.Duration, error) {
  376. if v, ok := s.data[key]; ok {
  377. if t, err := parseTime(v); err != nil {
  378. return 0, err
  379. } else {
  380. return time.Duration(t), nil
  381. }
  382. } else {
  383. return 0, &NoKeyError{Key: key, Section: s.Name}
  384. }
  385. }
  386. func parseTime(v string) (int64, error) {
  387. unit := int64(time.Nanosecond)
  388. subIdx := len(v)
  389. if strings.HasSuffix(v, "ms") {
  390. unit = int64(time.Millisecond)
  391. subIdx = subIdx - 2
  392. } else if strings.HasSuffix(v, "s") {
  393. unit = int64(time.Second)
  394. subIdx = subIdx - 1
  395. } else if strings.HasSuffix(v, "sec") {
  396. unit = int64(time.Second)
  397. subIdx = subIdx - 3
  398. } else if strings.HasSuffix(v, "m") {
  399. unit = int64(time.Minute)
  400. subIdx = subIdx - 1
  401. } else if strings.HasSuffix(v, "min") {
  402. unit = int64(time.Minute)
  403. subIdx = subIdx - 3
  404. } else if strings.HasSuffix(v, "h") {
  405. unit = int64(time.Hour)
  406. subIdx = subIdx - 1
  407. } else if strings.HasSuffix(v, "hour") {
  408. unit = int64(time.Hour)
  409. subIdx = subIdx - 4
  410. }
  411. b, err := strconv.ParseInt(v[:subIdx], 10, 64)
  412. if err != nil {
  413. return 0, err
  414. }
  415. return b * unit, nil
  416. }
  417. // Keys return all the section keys.
  418. func (s *Section) Keys() []string {
  419. keys := []string{}
  420. for k, _ := range s.data {
  421. keys = append(keys, k)
  422. }
  423. return keys
  424. }
  425. // An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
  426. // (The argument to Unmarshal must be a non-nil pointer.)
  427. type InvalidUnmarshalError struct {
  428. Type reflect.Type
  429. }
  430. func (e *InvalidUnmarshalError) Error() string {
  431. if e.Type == nil {
  432. return "goconf: Unmarshal(nil)"
  433. }
  434. if e.Type.Kind() != reflect.Ptr {
  435. return "goconf: Unmarshal(non-pointer " + e.Type.String() + ")"
  436. }
  437. return "goconf: Unmarshal(nil " + e.Type.String() + ")"
  438. }
  439. // Unmarshal parses the goconf struct and stores the result in the value
  440. // pointed to by v.
  441. //
  442. // Struct values encode as goconf objects. Each exported struct field
  443. // becomes a member of the object unless
  444. // - the field's tag is "-", or
  445. // - the field is empty and its tag specifies the "omitempty" option.
  446. // The empty values are false, 0, any
  447. // nil pointer or interface value, and any array, slice, map, or string of
  448. // length zero. The object's section and key string is the struct field name
  449. // but can be specified in the struct field's tag value. The "goconf" key in
  450. // the struct field's tag value is the key name, followed by an optional comma
  451. // and options. Examples:
  452. //
  453. // // Field is ignored by this package.
  454. // Field int `goconf:"-"`
  455. //
  456. // // Field appears in goconf section "base" as key "myName".
  457. // Field int `goconf:"base:myName"`
  458. //
  459. // // Field appears in goconf section "base" as key "myName", the value split
  460. // // by delimiter ",".
  461. // Field []string `goconf:"base:myName:,"`
  462. //
  463. // // Field appears in goconf section "base" as key "myName", the value split
  464. // // by delimiter "," and key-value is splited by "=".
  465. // Field map[int]string `goconf:"base:myName:,"`
  466. //
  467. // // Field appears in goconf section "base" as key "myName", the value
  468. // // conver to time.Duration. When has extra tag "time", then goconf can
  469. // // parse such "1h", "1s" config values.
  470. // //
  471. // // Note the extra tag "time" only effect the int64 (time.Duration is int64)
  472. // Field time.Duration `goconf:"base:myName:time"`
  473. //
  474. // // Field appears in goconf section "base" as key "myName", when has extra
  475. // // tag, then goconf can parse like "1gb", "1mb" config values.
  476. // //
  477. // // Note the extra tag "memory" only effect the int (memory size is int).
  478. // Field int `goconf:"base:myName:memory"`
  479. //
  480. func (c *Config) Unmarshal(v interface{}) error {
  481. vv := reflect.ValueOf(v)
  482. if vv.Kind() != reflect.Ptr || vv.IsNil() {
  483. return &InvalidUnmarshalError{reflect.TypeOf(v)}
  484. }
  485. rv := vv.Elem()
  486. rt := rv.Type()
  487. n := rv.NumField()
  488. // enum every struct field
  489. for i := 0; i < n; i++ {
  490. vf := rv.Field(i)
  491. tf := rt.Field(i)
  492. tag := tf.Tag.Get("goconf")
  493. // if tag empty or "-" ignore
  494. if tag == "-" || tag == "" || tag == "omitempty" {
  495. continue
  496. }
  497. tagArr := strings.SplitN(tag, ":", 3)
  498. if len(tagArr) < 2 {
  499. return errors.New(fmt.Sprintf("error tag: %s, must be section:field:delim(optional)", tag))
  500. }
  501. section := tagArr[0]
  502. key := tagArr[1]
  503. s := c.Get(section)
  504. if s == nil {
  505. // no config section
  506. continue
  507. }
  508. value, ok := s.data[key]
  509. if !ok {
  510. // no confit key
  511. continue
  512. }
  513. switch vf.Kind() {
  514. case reflect.String:
  515. vf.SetString(value)
  516. case reflect.Bool:
  517. vf.SetBool(parseBool(value))
  518. case reflect.Float32:
  519. if tmp, err := strconv.ParseFloat(value, 32); err != nil {
  520. return err
  521. } else {
  522. vf.SetFloat(tmp)
  523. }
  524. case reflect.Float64:
  525. if tmp, err := strconv.ParseFloat(value, 64); err != nil {
  526. return err
  527. } else {
  528. vf.SetFloat(tmp)
  529. }
  530. case reflect.Int:
  531. if len(tagArr) == 3 {
  532. format := tagArr[2]
  533. // parse memory size
  534. if format == "memory" {
  535. if tmp, err := parseMemory(value); err != nil {
  536. return err
  537. } else {
  538. vf.SetInt(int64(tmp))
  539. }
  540. } else {
  541. return errors.New(fmt.Sprintf("unknown tag: %s in struct field: %s (support tags: \"memory\")", format, tf.Name))
  542. }
  543. } else {
  544. if tmp, err := strconv.ParseInt(value, 10, 32); err != nil {
  545. return err
  546. } else {
  547. vf.SetInt(tmp)
  548. }
  549. }
  550. case reflect.Int8:
  551. if tmp, err := strconv.ParseInt(value, 10, 8); err != nil {
  552. return err
  553. } else {
  554. vf.SetInt(tmp)
  555. }
  556. case reflect.Int16:
  557. if tmp, err := strconv.ParseInt(value, 10, 16); err != nil {
  558. return err
  559. } else {
  560. vf.SetInt(tmp)
  561. }
  562. case reflect.Int32:
  563. if tmp, err := strconv.ParseInt(value, 10, 32); err != nil {
  564. return err
  565. } else {
  566. vf.SetInt(tmp)
  567. }
  568. case reflect.Int64:
  569. if len(tagArr) == 3 {
  570. format := tagArr[2]
  571. // parse time
  572. if format == "time" {
  573. if tmp, err := parseTime(value); err != nil {
  574. return err
  575. } else {
  576. vf.SetInt(tmp)
  577. }
  578. } else {
  579. return errors.New(fmt.Sprintf("unknown tag: %s in struct field: %s (support tags: \"time\")", format, tf.Name))
  580. }
  581. } else {
  582. if tmp, err := strconv.ParseInt(value, 10, 64); err != nil {
  583. return err
  584. } else {
  585. vf.SetInt(tmp)
  586. }
  587. }
  588. case reflect.Uint:
  589. if tmp, err := strconv.ParseUint(value, 10, 32); err != nil {
  590. return err
  591. } else {
  592. vf.SetUint(tmp)
  593. }
  594. case reflect.Uint8:
  595. if tmp, err := strconv.ParseUint(value, 10, 8); err != nil {
  596. return err
  597. } else {
  598. vf.SetUint(tmp)
  599. }
  600. case reflect.Uint16:
  601. if tmp, err := strconv.ParseUint(value, 10, 16); err != nil {
  602. return err
  603. } else {
  604. vf.SetUint(tmp)
  605. }
  606. case reflect.Uint32:
  607. if tmp, err := strconv.ParseUint(value, 10, 32); err != nil {
  608. return err
  609. } else {
  610. vf.SetUint(tmp)
  611. }
  612. case reflect.Uint64:
  613. if tmp, err := strconv.ParseUint(value, 10, 64); err != nil {
  614. return err
  615. } else {
  616. vf.SetUint(tmp)
  617. }
  618. case reflect.Slice:
  619. delim := ","
  620. if len(tagArr) > 2 {
  621. delim = tagArr[2]
  622. }
  623. strs := strings.Split(value, delim)
  624. sli := reflect.MakeSlice(tf.Type, 0, len(strs))
  625. for _, str := range strs {
  626. vv, err := getValue(tf.Type.Elem().String(), str)
  627. if err != nil {
  628. return err
  629. }
  630. sli = reflect.Append(sli, vv)
  631. }
  632. vf.Set(sli)
  633. case reflect.Map:
  634. delim := ","
  635. if len(tagArr) > 2 {
  636. delim = tagArr[2]
  637. }
  638. strs := strings.Split(value, delim)
  639. m := reflect.MakeMap(tf.Type)
  640. for _, str := range strs {
  641. mapStrs := strings.SplitN(str, "=", 2)
  642. if len(mapStrs) < 2 {
  643. return errors.New(fmt.Sprintf("error map: %s, must be split by \"=\"", str))
  644. }
  645. vk, err := getValue(tf.Type.Key().String(), mapStrs[0])
  646. if err != nil {
  647. return err
  648. }
  649. vv, err := getValue(tf.Type.Elem().String(), mapStrs[1])
  650. if err != nil {
  651. return err
  652. }
  653. m.SetMapIndex(vk, vv)
  654. }
  655. vf.Set(m)
  656. default:
  657. return errors.New(fmt.Sprintf("cannot unmarshall unsuported kind: %s into struct field: %s", vf.Kind().String(), tf.Name))
  658. }
  659. }
  660. return nil
  661. }
  662. // getValue parse String to the type "t" reflect.Value.
  663. func getValue(t, v string) (reflect.Value, error) {
  664. var vv reflect.Value
  665. switch t {
  666. case "bool":
  667. d := parseBool(v)
  668. vv = reflect.ValueOf(d)
  669. case "int":
  670. d, err := strconv.ParseInt(v, 10, 32)
  671. if err != nil {
  672. return vv, err
  673. }
  674. vv = reflect.ValueOf(int(d))
  675. case "int8":
  676. d, err := strconv.ParseInt(v, 10, 8)
  677. if err != nil {
  678. return vv, err
  679. }
  680. vv = reflect.ValueOf(int8(d))
  681. case "int16":
  682. d, err := strconv.ParseInt(v, 10, 16)
  683. if err != nil {
  684. return vv, err
  685. }
  686. vv = reflect.ValueOf(int16(d))
  687. case "int32":
  688. d, err := strconv.ParseInt(v, 10, 32)
  689. if err != nil {
  690. return vv, err
  691. }
  692. vv = reflect.ValueOf(int32(d))
  693. case "int64":
  694. d, err := strconv.ParseInt(v, 10, 64)
  695. if err != nil {
  696. return vv, err
  697. }
  698. vv = reflect.ValueOf(int64(d))
  699. case "uint":
  700. d, err := strconv.ParseUint(v, 10, 32)
  701. if err != nil {
  702. return vv, err
  703. }
  704. vv = reflect.ValueOf(uint(d))
  705. case "uint8":
  706. d, err := strconv.ParseUint(v, 10, 8)
  707. if err != nil {
  708. return vv, err
  709. }
  710. vv = reflect.ValueOf(uint8(d))
  711. case "uint16":
  712. d, err := strconv.ParseUint(v, 10, 16)
  713. if err != nil {
  714. return vv, err
  715. }
  716. vv = reflect.ValueOf(uint16(d))
  717. case "uint32":
  718. d, err := strconv.ParseUint(v, 10, 32)
  719. if err != nil {
  720. return vv, err
  721. }
  722. vv = reflect.ValueOf(uint32(d))
  723. case "uint64":
  724. d, err := strconv.ParseUint(v, 10, 64)
  725. if err != nil {
  726. return vv, err
  727. }
  728. vv = reflect.ValueOf(uint64(d))
  729. case "float32":
  730. d, err := strconv.ParseFloat(v, 32)
  731. if err != nil {
  732. return vv, err
  733. }
  734. vv = reflect.ValueOf(float32(d))
  735. case "float64":
  736. d, err := strconv.ParseFloat(v, 64)
  737. if err != nil {
  738. return vv, err
  739. }
  740. vv = reflect.ValueOf(float64(d))
  741. case "string":
  742. vv = reflect.ValueOf(v)
  743. default:
  744. return vv, errors.New(fmt.Sprintf("unkown type: %s", t))
  745. }
  746. return vv, nil
  747. }