diff --git a/go.mod b/go.mod index b115841..8709dc6 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( go.etcd.io/etcd/client/v3 v3.5.13 golang.org/x/crypto v0.23.0 golang.org/x/sys v0.20.0 - gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( diff --git a/go.sum b/go.sum index 7800600..be55f52 100644 --- a/go.sum +++ b/go.sum @@ -285,8 +285,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/quick/encoding.go b/quick/encoding.go index b420e08..39e017a 100644 --- a/quick/encoding.go +++ b/quick/encoding.go @@ -30,7 +30,7 @@ import ( "time" etcd "go.etcd.io/etcd/client/v3" - yaml "gopkg.in/yaml.v2" + yaml "gopkg.in/yaml.v3" ) // ConfigEncoding is a generic interface which diff --git a/quick/quick_test.go b/quick/quick_test.go index 201d87a..cba0076 100644 --- a/quick/quick_test.go +++ b/quick/quick_test.go @@ -225,9 +225,9 @@ func TestYAMLFormat(t *testing.T) { user: guest password: nopassword directories: -- Work -- Documents -- Music + - Work + - Documents + - Music ` if runtime.GOOS == "windows" { diff --git a/xtime/time.go b/xtime/time.go index 3dfbf0a..0a4a569 100644 --- a/xtime/time.go +++ b/xtime/time.go @@ -18,7 +18,10 @@ package xtime import ( + "fmt" "time" + + "gopkg.in/yaml.v3" ) // Additional durations, a day is considered to be 24 hours @@ -53,3 +56,33 @@ func ParseDuration(s string) (time.Duration, error) { } return parseDuration(s) } + +// Duration is a wrapper around time.Duration that supports YAML and JSON +type Duration time.Duration + +// UnmarshalYAML implements yaml.Unmarshaler +func (d *Duration) UnmarshalYAML(value *yaml.Node) error { + if value.Kind == yaml.ScalarNode { + dur, err := ParseDuration(value.Value) + if err != nil { + return err + } + *d = Duration(dur) + return nil + } + return fmt.Errorf("unable to unmarshal %s", value.Tag) + +} + +// UnmarshalJSON implements json.Unmarshaler +func (d *Duration) UnmarshalJSON(bs []byte) error { + if len(bs) <= 2 { + return nil + } + dur, err := ParseDuration(string(bs[1 : len(bs)-1])) + if err != nil { + return err + } + *d = Duration(dur) + return nil +} diff --git a/xtime/time_unmarshal_test.go b/xtime/time_unmarshal_test.go new file mode 100644 index 0000000..15f356a --- /dev/null +++ b/xtime/time_unmarshal_test.go @@ -0,0 +1,58 @@ +// Copyright (c) 2015-2024 MinIO, Inc. +// +// This file is part of MinIO Object Storage stack +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package xtime + +import ( + "encoding/json" + "testing" + + "gopkg.in/yaml.v3" +) + +type testDuration struct { + A string `yaml:"a" json:"a"` + Dur Duration `yaml:"dur" json:"dur"` + DurationPointer *Duration `yaml:"durationPointer" json:"durationPointer"` +} + +func TestDuration_Unmarshal(t *testing.T) { + jsonData := []byte(`{"a":"1s","dur":"1w1s","durationPointer":"7d1s"}`) + yamlData := []byte(`a: 1s +dur: 1w1s +durationPointer: 7d1s`) + yamlTest := testDuration{} + if err := yaml.Unmarshal(yamlData, &yamlTest); err != nil { + t.Fatal(err) + } + jsonTest := testDuration{} + if err := json.Unmarshal(jsonData, &jsonTest); err != nil { + t.Fatal(err) + } + + jsonData = []byte(`{"a":"1s","dur":"1w1s"}`) + yamlData = []byte(`a: 1s +dur: 1w1s`) + + if err := yaml.Unmarshal(yamlData, &yamlTest); err != nil { + t.Fatal(err) + } + if err := json.Unmarshal(jsonData, &jsonTest); err != nil { + t.Fatal(err) + } + +}