feat: publish v1.0.0-rc.36-custom.1
Publish Docker image (Multi-arch) / Build & push (amd64) (push) Failing after 9m20s
Release (Linux, macOS, Windows) / Linux Release (push) Failing after 55m7s
Publish Docker image (Multi-arch) / Build & push (arm64) (push) Canceled after 0s
Release (Linux, macOS, Windows) / macOS Release (push) Canceled after 0s
Release (Linux, macOS, Windows) / Windows Release (push) Canceled after 0s
Publish Docker image (Multi-arch) / Create multi-arch manifests (push) Canceled after 0s
Publish Docker image (Multi-arch) / Build & push (amd64) (push) Failing after 9m20s
Release (Linux, macOS, Windows) / Linux Release (push) Failing after 55m7s
Publish Docker image (Multi-arch) / Build & push (arm64) (push) Canceled after 0s
Release (Linux, macOS, Windows) / macOS Release (push) Canceled after 0s
Release (Linux, macOS, Windows) / Windows Release (push) Canceled after 0s
Publish Docker image (Multi-arch) / Create multi-arch manifests (push) Canceled after 0s
This commit is contained in:
commit
bb7968b612
2381 files changed
+551494
No files matched your search
@@ -0,0 +1,96 @@
|
||||
package ionet
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
// decodeWithFlexibleTimes unmarshals API responses while tolerating timestamp strings
|
||||
// that omit timezone information by normalizing them to RFC3339Nano.
|
||||
func decodeWithFlexibleTimes(data []byte, target interface{}) error {
|
||||
var intermediate interface{}
|
||||
if err := json.Unmarshal(data, &intermediate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
normalized := normalizeTimeValues(intermediate)
|
||||
reencoded, err := json.Marshal(normalized)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return json.Unmarshal(reencoded, target)
|
||||
}
|
||||
|
||||
func decodeData[T any](data []byte, target *T) error {
|
||||
var wrapper struct {
|
||||
Data T `json:"data"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &wrapper); err != nil {
|
||||
return err
|
||||
}
|
||||
*target = wrapper.Data
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeDataWithFlexibleTimes[T any](data []byte, target *T) error {
|
||||
var wrapper struct {
|
||||
Data T `json:"data"`
|
||||
}
|
||||
if err := decodeWithFlexibleTimes(data, &wrapper); err != nil {
|
||||
return err
|
||||
}
|
||||
*target = wrapper.Data
|
||||
return nil
|
||||
}
|
||||
|
||||
func normalizeTimeValues(value interface{}) interface{} {
|
||||
switch v := value.(type) {
|
||||
case map[string]interface{}:
|
||||
return lo.MapValues(v, func(val interface{}, _ string) interface{} {
|
||||
return normalizeTimeValues(val)
|
||||
})
|
||||
case []interface{}:
|
||||
return lo.Map(v, func(item interface{}, _ int) interface{} {
|
||||
return normalizeTimeValues(item)
|
||||
})
|
||||
case string:
|
||||
if normalized, changed := normalizeTimeString(v); changed {
|
||||
return normalized
|
||||
}
|
||||
return v
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeTimeString(input string) (string, bool) {
|
||||
trimmed := strings.TrimSpace(input)
|
||||
if trimmed == "" {
|
||||
return input, false
|
||||
}
|
||||
|
||||
if _, err := time.Parse(time.RFC3339Nano, trimmed); err == nil {
|
||||
return trimmed, trimmed != input
|
||||
}
|
||||
if _, err := time.Parse(time.RFC3339, trimmed); err == nil {
|
||||
return trimmed, trimmed != input
|
||||
}
|
||||
|
||||
layouts := []string{
|
||||
"2006-01-02T15:04:05.999999999",
|
||||
"2006-01-02T15:04:05.999999",
|
||||
"2006-01-02T15:04:05",
|
||||
}
|
||||
|
||||
for _, layout := range layouts {
|
||||
if parsed, err := time.Parse(layout, trimmed); err == nil {
|
||||
return parsed.UTC().Format(time.RFC3339Nano), true
|
||||
}
|
||||
}
|
||||
|
||||
return input, false
|
||||
}
|
||||
Reference in new issue
Block a user