github.com/projectcalico/api@v0.0.0-20231218190037-9183ab93f33e/pkg/lib/numorstring/uint8orstring.go (about) 1 // Copyright (c) 2016 Tigera, Inc. All rights reserved. 2 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package numorstring 16 17 import ( 18 "encoding/json" 19 "strconv" 20 ) 21 22 // UInt8OrString is a type that can hold an uint8 or a string. When used in 23 // JSON or YAML marshalling and unmarshalling, it produces or consumes the 24 // inner type. This allows you to have, for example, a JSON field that can 25 // accept a name or number. 26 type Uint8OrString struct { 27 Type NumOrStringType `json:"type"` 28 NumVal uint8 `json:"numVal"` 29 StrVal string `json:"strVal"` 30 } 31 32 // UnmarshalJSON implements the json.Unmarshaller interface. 33 func (i *Uint8OrString) UnmarshalJSON(b []byte) error { 34 if b[0] == '"' { 35 var s string 36 if err := json.Unmarshal(b, &s); err != nil { 37 return err 38 } 39 40 num, err := strconv.ParseUint(s, 10, 8) 41 if err == nil { 42 i.Type = NumOrStringNum 43 i.NumVal = uint8(num) 44 } else { 45 i.Type = NumOrStringString 46 i.StrVal = s 47 } 48 49 return nil 50 } 51 i.Type = NumOrStringNum 52 return json.Unmarshal(b, &i.NumVal) 53 } 54 55 // MarshalJSON implements the json.Marshaller interface. 56 func (i Uint8OrString) MarshalJSON() ([]byte, error) { 57 if num, err := i.NumValue(); err == nil { 58 return json.Marshal(num) 59 } else { 60 return json.Marshal(i.StrVal) 61 } 62 } 63 64 // String returns the string value, or the Itoa of the int value. 65 func (i Uint8OrString) String() string { 66 if i.Type == NumOrStringString { 67 return i.StrVal 68 } 69 return strconv.FormatUint(uint64(i.NumVal), 10) 70 } 71 72 // NumValue returns the NumVal if type Int, or if 73 // it is a String, will attempt a conversion to int. 74 func (i Uint8OrString) NumValue() (uint8, error) { 75 if i.Type == NumOrStringString { 76 num, err := strconv.ParseUint(i.StrVal, 10, 8) 77 return uint8(num), err 78 } 79 return i.NumVal, nil 80 } 81 82 // OpenAPISchemaType is used by the kube-openapi generator when constructing 83 // the OpenAPI spec of this type. 84 // See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators 85 func (_ Uint8OrString) OpenAPISchemaType() []string { return []string{"string"} } 86 87 // OpenAPISchemaFormat is used by the kube-openapi generator when constructing 88 // the OpenAPI spec of this type. 89 // See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators 90 func (_ Uint8OrString) OpenAPISchemaFormat() string { return "int-or-string" }