mirror of
https://github.com/LukeHagar/plexgo.git
synced 2025-12-06 04:20:46 +00:00
ci: regenerated with OpenAPI Doc , Speakeasy CLI 1.615.2
This commit is contained in:
@@ -5,6 +5,7 @@ package utils
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
@@ -114,9 +115,9 @@ func MarshalJSON(v interface{}, tag reflect.StructTag, topLevel bool) ([]byte, e
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool, disallowUnknownFields bool) error {
|
||||
func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool, requiredFields []string) error {
|
||||
if reflect.TypeOf(v).Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("v must be a pointer")
|
||||
return errors.New("v must be a pointer")
|
||||
}
|
||||
|
||||
typ, val := dereferencePointers(reflect.TypeOf(v), reflect.ValueOf(v))
|
||||
@@ -124,19 +125,25 @@ func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool
|
||||
switch {
|
||||
case isModelType(typ):
|
||||
if topLevel || bytes.Equal(b, []byte("null")) {
|
||||
d := json.NewDecoder(bytes.NewReader(b))
|
||||
if disallowUnknownFields {
|
||||
d.DisallowUnknownFields()
|
||||
}
|
||||
return d.Decode(v)
|
||||
return json.Unmarshal(b, v)
|
||||
}
|
||||
|
||||
var unmarhsaled map[string]json.RawMessage
|
||||
var unmarshaled map[string]json.RawMessage
|
||||
|
||||
if err := json.Unmarshal(b, &unmarhsaled); err != nil {
|
||||
if err := json.Unmarshal(b, &unmarshaled); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
missingFields := []string{}
|
||||
for _, requiredField := range requiredFields {
|
||||
if _, ok := unmarshaled[requiredField]; !ok {
|
||||
missingFields = append(missingFields, requiredField)
|
||||
}
|
||||
}
|
||||
if len(missingFields) > 0 {
|
||||
return fmt.Errorf("missing required fields: %s", strings.Join(missingFields, ", "))
|
||||
}
|
||||
|
||||
var additionalPropertiesField *reflect.StructField
|
||||
var additionalPropertiesValue *reflect.Value
|
||||
|
||||
@@ -163,7 +170,7 @@ func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool
|
||||
|
||||
// If we receive a value for a const field ignore it but mark it as unmarshaled
|
||||
if field.Tag.Get("const") != "" {
|
||||
if r, ok := unmarhsaled[fieldName]; ok {
|
||||
if r, ok := unmarshaled[fieldName]; ok {
|
||||
val := string(r)
|
||||
|
||||
if strings.HasPrefix(val, `"`) && strings.HasSuffix(val, `"`) {
|
||||
@@ -178,13 +185,13 @@ func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool
|
||||
return fmt.Errorf("const field `%s` does not match expected value `%s` got `%s`", fieldName, constValue, val)
|
||||
}
|
||||
|
||||
delete(unmarhsaled, fieldName)
|
||||
delete(unmarshaled, fieldName)
|
||||
}
|
||||
} else if !field.IsExported() {
|
||||
continue
|
||||
}
|
||||
|
||||
value, ok := unmarhsaled[fieldName]
|
||||
value, ok := unmarshaled[fieldName]
|
||||
if !ok {
|
||||
defaultTag, defaultOk := field.Tag.Lookup("default")
|
||||
if defaultOk {
|
||||
@@ -192,26 +199,22 @@ func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool
|
||||
ok = true
|
||||
}
|
||||
} else {
|
||||
delete(unmarhsaled, fieldName)
|
||||
delete(unmarshaled, fieldName)
|
||||
}
|
||||
|
||||
if ok {
|
||||
if err := unmarshalValue(value, fieldVal, field.Tag, disallowUnknownFields); err != nil {
|
||||
if err := unmarshalValue(value, fieldVal, field.Tag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(unmarhsaled))
|
||||
for k := range unmarhsaled {
|
||||
keys := make([]string, 0, len(unmarshaled))
|
||||
for k := range unmarshaled {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
if len(keys) > 0 {
|
||||
if disallowUnknownFields && (additionalPropertiesField == nil || additionalPropertiesValue == nil) {
|
||||
return fmt.Errorf("unknown fields: %v", keys)
|
||||
}
|
||||
|
||||
if additionalPropertiesField != nil && additionalPropertiesValue != nil {
|
||||
typeOfMap := additionalPropertiesField.Type
|
||||
if additionalPropertiesValue.Type().Kind() == reflect.Interface {
|
||||
@@ -222,10 +225,10 @@ func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool
|
||||
|
||||
mapValue := reflect.MakeMap(typeOfMap)
|
||||
|
||||
for key, value := range unmarhsaled {
|
||||
for key, value := range unmarshaled {
|
||||
val := reflect.New(typeOfMap.Elem())
|
||||
|
||||
if err := unmarshalValue(value, val, additionalPropertiesField.Tag, disallowUnknownFields); err != nil {
|
||||
if err := unmarshalValue(value, val, additionalPropertiesField.Tag); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -244,7 +247,7 @@ func UnmarshalJSON(b []byte, v interface{}, tag reflect.StructTag, topLevel bool
|
||||
}
|
||||
}
|
||||
default:
|
||||
return unmarshalValue(b, reflect.ValueOf(v), tag, disallowUnknownFields)
|
||||
return unmarshalValue(b, reflect.ValueOf(v), tag)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -394,7 +397,7 @@ func handleDefaultConstValue(tagValue string, val interface{}, tag reflect.Struc
|
||||
return []byte(tagValue)
|
||||
}
|
||||
|
||||
func unmarshalValue(value json.RawMessage, v reflect.Value, tag reflect.StructTag, disallowUnknownFields bool) error {
|
||||
func unmarshalValue(value json.RawMessage, v reflect.Value, tag reflect.StructTag) error {
|
||||
if bytes.Equal(value, []byte("null")) {
|
||||
if v.CanAddr() {
|
||||
return json.Unmarshal(value, v.Addr().Interface())
|
||||
@@ -466,18 +469,18 @@ func unmarshalValue(value json.RawMessage, v reflect.Value, tag reflect.StructTa
|
||||
}
|
||||
}
|
||||
|
||||
var unmarhsaled map[string]json.RawMessage
|
||||
var unmarshaled map[string]json.RawMessage
|
||||
|
||||
if err := json.Unmarshal(value, &unmarhsaled); err != nil {
|
||||
if err := json.Unmarshal(value, &unmarshaled); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := reflect.MakeMap(typ)
|
||||
|
||||
for k, value := range unmarhsaled {
|
||||
for k, value := range unmarshaled {
|
||||
itemVal := reflect.New(typ.Elem())
|
||||
|
||||
if err := unmarshalValue(value, itemVal, tag, disallowUnknownFields); err != nil {
|
||||
if err := unmarshalValue(value, itemVal, tag); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -498,7 +501,7 @@ func unmarshalValue(value json.RawMessage, v reflect.Value, tag reflect.StructTa
|
||||
for index, value := range unmarshaled {
|
||||
itemVal := reflect.New(typ.Elem())
|
||||
|
||||
if err := unmarshalValue(value, itemVal, tag, disallowUnknownFields); err != nil {
|
||||
if err := unmarshalValue(value, itemVal, tag); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -616,11 +619,7 @@ func unmarshalValue(value json.RawMessage, v reflect.Value, tag reflect.StructTa
|
||||
val = v.Interface()
|
||||
}
|
||||
|
||||
d := json.NewDecoder(bytes.NewReader(value))
|
||||
if disallowUnknownFields {
|
||||
d.DisallowUnknownFields()
|
||||
}
|
||||
return d.Decode(val)
|
||||
return json.Unmarshal(value, val)
|
||||
}
|
||||
|
||||
func dereferencePointers(typ reflect.Type, val reflect.Value) (reflect.Type, reflect.Value) {
|
||||
|
||||
@@ -7,10 +7,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/LukeHagar/plexgo/retry"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -27,6 +29,17 @@ type Retries struct {
|
||||
StatusCodes []string
|
||||
}
|
||||
|
||||
var (
|
||||
// IETF RFC 7231 4.2 safe and idempotent HTTP methods for connection retries
|
||||
idempotentHTTPMethods = []string{
|
||||
http.MethodDelete,
|
||||
http.MethodGet,
|
||||
http.MethodHead,
|
||||
http.MethodOptions,
|
||||
http.MethodPut,
|
||||
}
|
||||
)
|
||||
|
||||
func Retry(ctx context.Context, r Retries, operation func() (*http.Response, error)) (*http.Response, error) {
|
||||
switch r.Config.Strategy {
|
||||
case "backoff":
|
||||
@@ -49,11 +62,48 @@ func Retry(ctx context.Context, r Retries, operation func() (*http.Response, err
|
||||
|
||||
res, err := operation()
|
||||
if err != nil {
|
||||
if !r.Config.RetryConnectionErrors {
|
||||
return retry.Permanent(err)
|
||||
}
|
||||
|
||||
var httpMethod string
|
||||
|
||||
// Use http.Request method if available
|
||||
if res != nil && res.Request != nil {
|
||||
httpMethod = res.Request.Method
|
||||
}
|
||||
|
||||
isIdempotentHTTPMethod := slices.Contains(idempotentHTTPMethods, httpMethod)
|
||||
urlError := new(url.Error)
|
||||
|
||||
if errors.As(err, &urlError) {
|
||||
if (urlError.Temporary() || urlError.Timeout()) && r.Config.RetryConnectionErrors {
|
||||
if urlError.Temporary() || urlError.Timeout() {
|
||||
return err
|
||||
}
|
||||
|
||||
// In certain error cases, the http.Request may not have
|
||||
// been populated, so use url.Error.Op which only has its
|
||||
// first character capitalized from the original request
|
||||
// HTTP method.
|
||||
if httpMethod == "" {
|
||||
httpMethod = strings.ToUpper(urlError.Op)
|
||||
}
|
||||
|
||||
isIdempotentHTTPMethod = slices.Contains(idempotentHTTPMethods, httpMethod)
|
||||
|
||||
// Connection closed
|
||||
if errors.Is(urlError.Err, io.EOF) && isIdempotentHTTPMethod {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// syscall detection is not available on every platform, so
|
||||
// fallback to best effort string detection.
|
||||
isBrokenPipeError := strings.Contains(err.Error(), "broken pipe")
|
||||
isConnectionResetError := strings.Contains(err.Error(), "connection reset")
|
||||
|
||||
if (isBrokenPipeError || isConnectionResetError) && isIdempotentHTTPMethod {
|
||||
return err
|
||||
}
|
||||
|
||||
return retry.Permanent(err)
|
||||
|
||||
@@ -40,8 +40,8 @@ func UnmarshalJsonFromResponseBody(body io.Reader, out interface{}, tag string)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error reading response body: %w", err)
|
||||
}
|
||||
if err := UnmarshalJSON(data, out, reflect.StructTag(tag), true, false); err != nil {
|
||||
return fmt.Errorf("error unmarshalling json response body: %w", err)
|
||||
if err := UnmarshalJSON(data, out, reflect.StructTag(tag), true, nil); err != nil {
|
||||
return fmt.Errorf("error unmarshaling json response body: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user