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  }