Something went wrong. Try again.
forked from tailscale/tailscale
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124// Copyright (c) Tailscale Inc & contributors// SPDX-License-Identifier: BSD-3-Clause
package jsonformat
import ( "time"
"github.com/go-json-experiment/json" "github.com/go-json-experiment/json/jsontext")
// DurationNano is a [time.Duration] that represents a duration as// a JSON number of nanoseconds. If [json.StringifyNumbers] is specified,// then it represents the duration as a JSON number within a JSON string.//// This format is what v1 [encoding/json] historically used for durations.// It is not recommended that newly defined types represent durations// using this format, as a standalone JSON number lacks context// as to the units of the duration.type DurationNano struct{ time.Duration }
func (d DurationNano) MarshalJSON() ([]byte, error) { return json.Marshal(d)}
func (d DurationNano) MarshalJSONTo(enc *jsontext.Encoder) error { // Marshaling as an int64 directly allows us to properly handle // the [json.StringifyNumbers] option. return json.MarshalEncode(enc, int64(d.Duration))}
func (d *DurationNano) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, d)}
func (d *DurationNano) UnmarshalJSONFrom(dec *jsontext.Decoder) error { // Unmarshaling into an int64 directly allows us to properly handle // the [json.StringifyNumbers] option. return json.UnmarshalDecode(dec, (*int64)(&d.Duration))}
// DurationUnits is a [time.Duration] that represents a duration as// a JSON string using the format of [time.Duration.String].//// While this format is human-readable (e.g., "43m17.152s"),// it is also highly specific to the Go ecosystem// (and not used elsewhere in the industry).type DurationUnits struct{ time.Duration }
func (d DurationUnits) MarshalJSON() ([]byte, error) { return json.Marshal(d)}
func (d DurationUnits) MarshalJSONTo(enc *jsontext.Encoder) error { b := enc.AvailableBuffer() b = append(b, '"') b = append(b, d.Duration.String()...) b = append(b, '"') return enc.WriteValue(b)}
func (d *DurationUnits) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, d)}
func (d *DurationUnits) UnmarshalJSONFrom(dec *jsontext.Decoder) error { isNull := dec.PeekKind() == 'n' var s string if err := json.UnmarshalDecode(dec, &s); err != nil { return err } if isNull { d.Duration = 0 return nil } var err error d.Duration, err = time.ParseDuration(s) return err}
// DurationISO8601 is a [time.Duration] that represents a duration as// a JSON string using a subset of the ISO 8601 format.// In particular, it uses the exact grammar of ISO 8601 that JavaScript// uses for its Temporal.Duration type.//// While this format is relatively novel in the Go ecosystem,// the fact that JSON finds its heritage in JavaScript and that// JavaScript has adopted ISO 8601 as the JSON representation for durations// suggests that JavaScript's particular flavor of ISO 8601 may well become// the de facto standard for representing durations across the industry.type DurationISO8601 struct{ time.Duration }
func (d DurationISO8601) MarshalJSON() ([]byte, error) { return json.Marshal(d)}
func (d DurationISO8601) MarshalJSONTo(enc *jsontext.Encoder) error { b := enc.AvailableBuffer() b = append(b, '"') b = appendDurationISO8601(b, d.Duration) b = append(b, '"') return enc.WriteValue(b)}
func (d *DurationISO8601) UnmarshalJSON(b []byte) error { return json.Unmarshal(b, d)}
func (d *DurationISO8601) UnmarshalJSONFrom(dec *jsontext.Decoder) error { isNull := dec.PeekKind() == 'n' var s string if err := json.UnmarshalDecode(dec, &s); err != nil { return err } if isNull { d.Duration = 0 return nil } var err error d.Duration, err = parseDurationISO8601([]byte(s)) return err}