github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/utils/strings.go (about) 1 /* 2 Copyright 2021 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package utils 18 19 import ( 20 "encoding/json" 21 "strings" 22 23 "github.com/gravitational/trace" 24 ) 25 26 // Strings is a list of string that can unmarshal from list of strings 27 // or a scalar string from scalar yaml or json property 28 type Strings []string 29 30 // UnmarshalJSON unmarshals scalar string or strings slice to Strings 31 func (s *Strings) UnmarshalJSON(data []byte) error { 32 if len(data) == 0 { 33 return nil 34 } 35 var stringVar string 36 if err := json.Unmarshal(data, &stringVar); err == nil { 37 *s = []string{stringVar} 38 return nil 39 } 40 var stringsVar []string 41 if err := json.Unmarshal(data, &stringsVar); err != nil { 42 return trace.Wrap(err) 43 } 44 *s = stringsVar 45 return nil 46 } 47 48 // UnmarshalYAML is used to allow Strings to unmarshal from 49 // scalar string value or from the list 50 func (s *Strings) UnmarshalYAML(unmarshal func(interface{}) error) error { 51 // try unmarshal as string 52 var val string 53 err := unmarshal(&val) 54 if err == nil { 55 *s = []string{val} 56 return nil 57 } 58 59 // try unmarshal as slice 60 var slice []string 61 err = unmarshal(&slice) 62 if err == nil { 63 *s = slice 64 return nil 65 } 66 67 return err 68 } 69 70 // MarshalJSON marshals to scalar value 71 // if there is only one value in the list 72 // to list otherwise 73 func (s Strings) MarshalJSON() ([]byte, error) { 74 if len(s) == 1 { 75 return json.Marshal(s[0]) 76 } 77 return json.Marshal([]string(s)) 78 } 79 80 // MarshalYAML marshals to scalar value 81 // if there is only one value in the list, 82 // marshals to list otherwise 83 func (s Strings) MarshalYAML() (interface{}, error) { 84 if len(s) == 1 { 85 return s[0], nil 86 } 87 return []string(s), nil 88 } 89 90 // CopyStrings makes a deep copy of the passed in string slice and returns 91 // the copy. 92 func CopyStrings(in []string) []string { 93 if in == nil { 94 return nil 95 } 96 97 out := make([]string, len(in)) 98 copy(out, in) 99 100 return out 101 } 102 103 // MapToStrings collects keys and values of a map into a slice of strings. 104 func MapToStrings(m map[string]string) []string { 105 s := make([]string, 0, len(m)*2) 106 for key, value := range m { 107 s = append(s, key, value) 108 } 109 return s 110 } 111 112 // ToLowerStrings lower cases each string in a slice. 113 func ToLowerStrings(strs []string) []string { 114 lowerCasedStrs := make([]string, len(strs)) 115 for i, s := range strs { 116 lowerCasedStrs[i] = strings.ToLower(s) 117 } 118 119 return lowerCasedStrs 120 }