types.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package ini
  2. // Types of with values more readable for humans
  3. import (
  4. "fmt"
  5. "net"
  6. "strconv"
  7. "strings"
  8. "time"
  9. )
  10. // IP is equalient to net.IP but with custom Marshaler-interface
  11. type IP struct {
  12. net.IP
  13. }
  14. // MarshalINI will marshal the IP into IPv4 or IPv6 readable format, e.g
  15. // 127.0.0.1 or ::
  16. func (i *IP) MarshalINI() ([]byte, error) {
  17. if ip := i.To4(); ip != nil {
  18. return []byte(ip.String()), nil
  19. }
  20. if ip := i.To16(); ip != nil {
  21. return []byte(ip.String()), nil
  22. }
  23. return nil, nil
  24. }
  25. // UnmarshalINI will unmarshal the value produced by MarshalINI, e.g
  26. // 127.0.0.1 or :: into a net.IP
  27. func (i *IP) UnmarshalINI(b []byte) error {
  28. i.IP = net.ParseIP(string(b))
  29. return nil
  30. }
  31. // Time is equalient to time.Time but with custom Marshaler-interface
  32. type Time struct {
  33. time.Time
  34. }
  35. // MarshalINI will marshal the time into RFC822
  36. func (i *Time) MarshalINI() ([]byte, error) {
  37. if i.IsZero() {
  38. return nil, nil
  39. }
  40. return []byte(i.Format(time.RFC822)), nil
  41. }
  42. // UnmarshalINI will unmarshal the time from RFC822
  43. func (i *Time) UnmarshalINI(b []byte) error {
  44. var err error
  45. (*i).Time, err = time.Parse(time.RFC822, string(b))
  46. return err
  47. }
  48. // Date is equalient to time.Time but with custom Marshaler-interface to store only the date
  49. type Date struct {
  50. time.Time
  51. }
  52. // MarshalINI will marshal the time into a string of format y-d-m-timezone-offset
  53. func (i *Date) MarshalINI() ([]byte, error) {
  54. if i.IsZero() {
  55. return nil, nil
  56. }
  57. y, m, d := i.Date()
  58. tz, off := i.Zone()
  59. return []byte(fmt.Sprintf("%d-%d-%d-%s-%d", y, m, d, tz, off)), nil
  60. }
  61. // UnmarshalINI will unmarshal a string formatted as y-m-d-timezone-offset
  62. func (i *Date) UnmarshalINI(b []byte) error {
  63. (*i).Time = time.Now()
  64. spl := strings.Split(string(b), "-")
  65. if len(spl) != 5 {
  66. return fmt.Errorf("Invalid format %s, need d-m-y-tz-offset", string(b))
  67. }
  68. y, err := strconv.ParseInt(spl[0], 10, 32)
  69. if err != nil {
  70. return err
  71. }
  72. m, err := strconv.ParseInt(spl[1], 10, 32)
  73. if err != nil {
  74. return err
  75. }
  76. d, err := strconv.ParseInt(spl[2], 10, 32)
  77. if err != nil {
  78. return err
  79. }
  80. off, err := strconv.ParseInt(spl[4], 10, 32)
  81. if err != nil {
  82. return err
  83. }
  84. l := time.FixedZone(spl[3], int(off))
  85. if err != nil {
  86. return err
  87. }
  88. diff := time.Date(int(y), time.Month(m), int(d), 0, 0, 0, 0, l).Sub(i.Time)
  89. i.Time.Add(diff)
  90. return nil
  91. }