package ini // Types of with values more readable for humans import ( "fmt" "net" "strconv" "strings" "time" ) // IP is equalient to net.IP but with custom Marshaler-interface type IP struct { net.IP } // MarshalINI will marshal the IP into IPv4 or IPv6 readable format, e.g // 127.0.0.1 or :: func (i *IP) MarshalINI() ([]byte, error) { if ip := i.To4(); ip != nil { return []byte(ip.String()), nil } if ip := i.To16(); ip != nil { return []byte(ip.String()), nil } return nil, nil } // UnmarshalINI will unmarshal the value produced by MarshalINI, e.g // 127.0.0.1 or :: into a net.IP func (i *IP) UnmarshalINI(b []byte) error { i.IP = net.ParseIP(string(b)) return nil } // Time is equalient to time.Time but with custom Marshaler-interface type Time struct { time.Time } // MarshalINI will marshal the time into RFC822 func (i *Time) MarshalINI() ([]byte, error) { if i.IsZero() { return nil, nil } return []byte(i.Format(time.RFC822)), nil } // UnmarshalINI will unmarshal the time from RFC822 func (i *Time) UnmarshalINI(b []byte) error { var err error (*i).Time, err = time.Parse(time.RFC822, string(b)) return err } // Date is equalient to time.Time but with custom Marshaler-interface to store only the date type Date struct { time.Time } // MarshalINI will marshal the time into a string of format y-d-m-timezone-offset func (i *Date) MarshalINI() ([]byte, error) { if i.IsZero() { return nil, nil } y, m, d := i.Date() tz, off := i.Zone() return []byte(fmt.Sprintf("%d-%d-%d-%s-%d", y, m, d, tz, off)), nil } // UnmarshalINI will unmarshal a string formatted as y-m-d-timezone-offset func (i *Date) UnmarshalINI(b []byte) error { (*i).Time = time.Now() spl := strings.Split(string(b), "-") if len(spl) != 5 { return fmt.Errorf("Invalid format %s, need d-m-y-tz-offset", string(b)) } y, err := strconv.ParseInt(spl[0], 10, 32) if err != nil { return err } m, err := strconv.ParseInt(spl[1], 10, 32) if err != nil { return err } d, err := strconv.ParseInt(spl[2], 10, 32) if err != nil { return err } off, err := strconv.ParseInt(spl[4], 10, 32) if err != nil { return err } l := time.FixedZone(spl[3], int(off)) if err != nil { return err } diff := time.Date(int(y), time.Month(m), int(d), 0, 0, 0, 0, l).Sub(i.Time) i.Time.Add(diff) return nil }