github.com/drone/go-convert@v0.0.0-20240307072510-6bd371c65e61/convert/harness/yaml/unit.go (about) 1 // Copyright 2022 Harness, Inc. 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 yaml 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "strconv" 21 "strings" 22 "time" 23 24 "github.com/docker/go-units" 25 ) 26 27 // BytesSize stores a human-readable size in bytes, 28 // kibibytes, mebibytes, gibibytes, or tebibytes 29 // (eg. "44kiB", "17MiB"). 30 type BytesSize int64 31 32 // UnmarshalYAML implements yaml unmarshalling. 33 func (b *BytesSize) UnmarshalYAML(unmarshal func(interface{}) error) error { 34 var intType int64 35 if err := unmarshal(&intType); err == nil { 36 *b = BytesSize(intType) 37 return nil 38 } 39 40 var stringType string 41 if err := unmarshal(&stringType); err != nil { 42 return err 43 } 44 45 intType, err := units.RAMInBytes(stringType) 46 if err == nil { 47 *b = BytesSize(intType) 48 } 49 return err 50 } 51 52 // MarshalJSON makes UnitBytes implement json.Marshaler 53 func (b *BytesSize) MarshalJSON() ([]byte, error) { 54 return json.Marshal(b.String()) 55 } 56 57 // UnmarshalJSON implements json unmarshalling. 58 func (b *BytesSize) UnmarshalJSON(data []byte) error { 59 var intType int64 60 if err := json.Unmarshal(data, &intType); err == nil { 61 *b = BytesSize(intType) 62 return nil 63 } 64 65 var stringType string 66 if err := json.Unmarshal(data, &stringType); err != nil { 67 return err 68 } 69 70 intType, err := units.RAMInBytes(stringType) 71 if err == nil { 72 *b = BytesSize(intType) 73 } 74 return err 75 } 76 77 // String returns a human-readable size in bytes, 78 // kibibytes, mebibytes, gibibytes, or tebibytes 79 // (eg. "44kiB", "17MiB"). 80 func (b BytesSize) String() string { 81 return units.BytesSize(float64(b)) 82 } 83 84 // MilliSize will convert cpus to millicpus as int64. 85 // for instance "1" will be converted to 1000 and "100m" to 100 86 type MilliSize int64 87 88 // UnmarshalYAML implements yaml unmarshalling. 89 func (m *MilliSize) UnmarshalYAML(unmarshal func(interface{}) error) error { 90 var intType int64 91 if err := unmarshal(&intType); err == nil { 92 *m = MilliSize(intType * 1000) 93 return nil 94 } 95 96 var stringType string 97 if err := unmarshal(&stringType); err != nil { 98 return err 99 } 100 if strings.HasSuffix(stringType, "m") { 101 i, err := strconv.ParseInt(strings.TrimSuffix(stringType, "m"), 10, 64) 102 if err != nil { 103 return err 104 } 105 *m = MilliSize(i) 106 return nil 107 } 108 return fmt.Errorf("cannot unmarshal cpu millis") 109 } 110 111 // UnmarshalJSON implements json unmarshalling. 112 func (m *MilliSize) UnmarshalJSON(data []byte) error { 113 var intType int64 114 if err := json.Unmarshal(data, &intType); err == nil { 115 *m = MilliSize(intType * 1000) 116 return nil 117 } 118 119 var stringType string 120 if err := json.Unmarshal(data, &stringType); err != nil { 121 return err 122 } 123 if strings.HasSuffix(stringType, "m") { 124 i, err := strconv.ParseInt(strings.TrimSuffix(stringType, "m"), 10, 64) 125 if err != nil { 126 return err 127 } 128 *m = MilliSize(i) 129 return nil 130 } 131 return fmt.Errorf("cannot unmarshal %s into cpu millis", string(data)) 132 } 133 134 // MarshalJSON makes implements json.Marshaler 135 func (m *MilliSize) MarshalJSON() ([]byte, error) { 136 return json.Marshal(m.String()) 137 } 138 139 // String returns a human-readable cpu millis, 140 // (eg. "1000", "10"). 141 func (m MilliSize) String() string { 142 if m == 0 { 143 return "0" 144 } else { 145 return strconv.FormatInt(int64(m), 10) 146 } 147 } 148 149 // 150 // 151 // 152 153 // Duration is a wrapper around time.Duration which supports correct 154 // marshaling to YAML and JSON. In particular, it marshals into strings, which 155 // can be used as map keys in json. 156 type Duration struct { 157 time.Duration 158 } 159 160 // UnmarshalJSON implements the json.Unmarshaller interface. 161 func (d *Duration) UnmarshalJSON(b []byte) error { 162 var str string 163 err := json.Unmarshal(b, &str) 164 if err != nil { 165 return err 166 } 167 168 pd, err := time.ParseDuration(str) 169 if err != nil { 170 return err 171 } 172 d.Duration = pd 173 return nil 174 } 175 176 // MarshalJSON implements the json.Marshaler interface. 177 func (d Duration) MarshalJSON() ([]byte, error) { 178 if d.Duration == 0 { 179 return json.Marshal("") 180 } 181 return json.Marshal(d.Duration.String()) 182 }