github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/caas/specs/types.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package specs
     5  
     6  import (
     7  	"encoding/json"
     8  	"fmt"
     9  	"strconv"
    10  )
    11  
    12  // IntOrString is a type that can hold an int32 or a string.  When used in
    13  // JSON or YAML marshalling and unmarshalling, it produces or consumes the
    14  // inner type.  This allows you to have, for example, a JSON field that can
    15  // accept a name or number.
    16  // It is ported from k8s.io/apimachinery/pkg/util/intstr/intstr.go to avoid introducing k8s dependency in top level package.
    17  type IntOrString struct {
    18  	Type   Type   `json:"type"`
    19  	IntVal int32  `json:"intVal,omitempty"`
    20  	StrVal string `json:"strVal,omitempty"`
    21  }
    22  
    23  // Type represents the stored type of IntOrString.
    24  type Type int64
    25  
    26  const (
    27  	// Int indicates the IntOrString holds an int.
    28  	Int Type = iota
    29  	// String indicates the IntOrString holds a string.
    30  	String
    31  )
    32  
    33  // UnmarshalJSON implements the json.Unmarshaller interface.
    34  func (intstr *IntOrString) UnmarshalJSON(value []byte) error {
    35  	if value[0] == '"' {
    36  		intstr.Type = String
    37  		return json.Unmarshal(value, &intstr.StrVal)
    38  	}
    39  	intstr.Type = Int
    40  	return json.Unmarshal(value, &intstr.IntVal)
    41  }
    42  
    43  // String returns the string value, or the Itoa of the int value.
    44  func (intstr *IntOrString) String() string {
    45  	if intstr.Type == String {
    46  		return intstr.StrVal
    47  	}
    48  	return strconv.Itoa(intstr.IntValue())
    49  }
    50  
    51  // IntValue returns the IntVal if type Int, or if
    52  // it is a String, will attempt a conversion to int.
    53  func (intstr *IntOrString) IntValue() int {
    54  	if intstr.Type == String {
    55  		i, _ := strconv.Atoi(intstr.StrVal)
    56  		return i
    57  	}
    58  	return int(intstr.IntVal)
    59  }
    60  
    61  // MarshalJSON implements the json.Marshaller interface.
    62  func (intstr IntOrString) MarshalJSON() ([]byte, error) {
    63  	switch intstr.Type {
    64  	case Int:
    65  		return json.Marshal(intstr.IntVal)
    66  	case String:
    67  		return json.Marshal(intstr.StrVal)
    68  	default:
    69  		return []byte{}, fmt.Errorf("impossible IntOrString.Type")
    70  	}
    71  }