go/protocol/iso/types.go (93 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. package iso import ( "bytes" "encoding/base64" "strings" "time" "github.com/relvacode/iso8601" "github.com/sosodev/duration" ) // Wrappers for the native Go time types that will serialize to ISO 8601. type ( // Date is a date in ISO 8601 format, per RFC 3339. Date time.Time // DateTime is a date and time in ISO 8601 format, per RFC 3339. DateTime time.Time // Duration is a duration in ISO 8601 format. Duration time.Duration // Time is a time in ISO 8601 format, per RFC 3339. Time time.Time // ByteSlice is a wrapper for the native Go byte slice that will serialize // to Base64. ByteSlice []byte ) // full-date (0) and full-time (1) schemas, as defined by RFC3339 section 5.6. var ( format = strings.Split(time.RFC3339, "T") zeroes = strings.Split(time.Time{}.Format(time.RFC3339), "T") ) // String returns the date as an ISO 8601 string. func (d Date) String() string { return time.Time(d).Format(format[0]) } // MarshalText marshals the date to an ISO 8601 string. func (d Date) MarshalText() ([]byte, error) { return []byte(d.String()), nil } // UnmarshalText unmarshals the date from an ISO 8601 string. func (d *Date) UnmarshalText(b []byte) error { if !bytes.ContainsAny(b, "tT") { b = []byte(string(b) + "T" + zeroes[1]) } parsed, err := iso8601.Parse(b) if err != nil { return err } *d = Date(parsed) return nil } // String returns the date-time as an ISO 8601 string. func (dt DateTime) String() string { return time.Time(dt).Format(time.RFC3339) } // MarshalText marshals the date-time to an ISO 8601 string. func (dt DateTime) MarshalText() ([]byte, error) { return []byte(dt.String()), nil } // UnmarshalText unmarshals the date-time from an ISO 8601 string. func (dt *DateTime) UnmarshalText(b []byte) error { parsed, err := iso8601.Parse(b) if err != nil { return err } *dt = DateTime(parsed) return nil } // String returns the duration as an ISO 8601 string. func (d Duration) String() string { return duration.Format(time.Duration(d)) } // MarshalText marshals the duration to an ISO 8601 string. func (d Duration) MarshalText() ([]byte, error) { return []byte(d.String()), nil } // UnmarshalText unmarshals the duration from an ISO 8601 string. func (d *Duration) UnmarshalText(b []byte) error { parsed, err := duration.Parse(string(b)) if err != nil { return err } *d = Duration(parsed.ToTimeDuration()) return nil } // String returns the time as an ISO 8601 string. func (t Time) String() string { return time.Time(t).Format(format[1]) } // MarshalText marshals the time to an ISO 8601 string. func (t Time) MarshalText() ([]byte, error) { return []byte(t.String()), nil } // UnmarshalText unmarshals the time from an ISO 8601 string. func (t *Time) UnmarshalText(b []byte) error { if !bytes.ContainsAny(b, "tT") { b = []byte(zeroes[0] + "T" + string(b)) } parsed, err := iso8601.Parse(b) if err != nil { return err } *t = Time(parsed) return nil } // String returns the byte slice as a Base64 string. func (bs ByteSlice) String() string { return base64.StdEncoding.EncodeToString(bs) } // MarshalText marshals the byte slice to a Base64 string. func (bs ByteSlice) MarshalText() ([]byte, error) { return []byte(bs.String()), nil } // UnmarshalText unmarshals the byte slice from a Base64 string. func (bs *ByteSlice) UnmarshalText(b []byte) error { var err error *bs, err = base64.StdEncoding.DecodeString(string(b)) return err }