github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/value/string.go (about) 1 package value 2 3 import ( 4 "fmt" 5 6 "go.starlark.net/starlark" 7 ) 8 9 type Stringable struct { 10 Value string 11 IsSet bool 12 } 13 14 func (s *Stringable) Unpack(v starlark.Value) error { 15 str, ok := AsString(v) 16 if !ok { 17 return fmt.Errorf("Value should be convertible to string, but is type %s", v.Type()) 18 } 19 s.Value = str 20 s.IsSet = true 21 return nil 22 } 23 24 type ImplicitStringer interface { 25 ImplicitString() string 26 } 27 28 // Wrapper around starlark.AsString 29 func AsString(x starlark.Value) (string, bool) { 30 is, ok := x.(ImplicitStringer) 31 if ok { 32 return is.ImplicitString(), true 33 } 34 return starlark.AsString(x) 35 } 36 37 type StringList []string 38 39 var _ starlark.Unpacker = &StringList{} 40 41 // Unpack an argument that can be expressed as a list or tuple of strings. 42 func (s *StringList) Unpack(v starlark.Value) error { 43 *s = nil 44 if v == nil { 45 return nil 46 } 47 48 var iter starlark.Iterator 49 switch x := v.(type) { 50 case *starlark.List: 51 iter = x.Iterate() 52 case starlark.Tuple: 53 iter = x.Iterate() 54 case starlark.NoneType: 55 return nil 56 default: 57 return fmt.Errorf("value should be a List or Tuple of strings, but is of type %s", v.Type()) 58 } 59 60 defer iter.Done() 61 var item starlark.Value 62 for iter.Next(&item) { 63 sv, ok := AsString(item) 64 if !ok { 65 return fmt.Errorf("value should contain only strings, but element %q was of type %s", item.String(), item.Type()) 66 } 67 *s = append(*s, sv) 68 } 69 70 return nil 71 } 72 73 type StringOrStringList struct { 74 Values []string 75 IsSet bool 76 } 77 78 var _ starlark.Unpacker = &StringOrStringList{} 79 80 // Unpack an argument that can either be expressed as 81 // a string or as a list of strings. 82 func (s *StringOrStringList) Unpack(v starlark.Value) error { 83 s.Values = nil 84 if v == nil { 85 return nil 86 } 87 88 vs, ok := AsString(v) 89 if ok { 90 s.Values = []string{vs} 91 s.IsSet = true 92 return nil 93 } 94 95 var iter starlark.Iterator 96 switch x := v.(type) { 97 case *starlark.List: 98 iter = x.Iterate() 99 case starlark.Tuple: 100 iter = x.Iterate() 101 case starlark.NoneType: 102 return nil 103 default: 104 return fmt.Errorf("value should be a string or List or Tuple of strings, but is of type %s", v.Type()) 105 } 106 107 defer iter.Done() 108 var item starlark.Value 109 for iter.Next(&item) { 110 sv, ok := AsString(item) 111 if !ok { 112 return fmt.Errorf("list should contain only strings, but element %q was of type %s", item.String(), item.Type()) 113 } 114 s.Values = append(s.Values, sv) 115 } 116 117 s.IsSet = true 118 return nil 119 }