github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/pkg/projectfile/nameval.go (about)

     1  package projectfile
     2  
     3  import (
     4  	"gopkg.in/yaml.v2"
     5  )
     6  
     7  type NameVal struct {
     8  	Name  string `yaml:"name"`
     9  	Value string `yaml:"value"`
    10  }
    11  
    12  func (nv *NameVal) UnmarshalYAML(unmarshal func(interface{}) error) error {
    13  	data := make(map[string]interface{})
    14  	if err := unmarshal(&data); err != nil {
    15  		return err
    16  	}
    17  
    18  	if len(data) == 1 { // likely short-hand `{name}: {value}` field
    19  		ssData, err := ensureMapStrStr(data)
    20  		if err != nil {
    21  			return err
    22  		}
    23  
    24  		for k, v := range ssData {
    25  			nv.Name, nv.Value = k, v
    26  			break
    27  		}
    28  
    29  	} else { // likely long-form `name: {name}` and `value: {value}` fields
    30  		type Tmp NameVal
    31  		var tmp Tmp
    32  		if err := unmarshal(&tmp); err != nil {
    33  			return err
    34  		}
    35  		*nv = NameVal(tmp)
    36  	}
    37  
    38  	return nil
    39  }
    40  
    41  // ensureMapStrStr will run the map[string]interface{} back through the yaml
    42  // unmarshalling so that any invalid values retain the yaml package error
    43  // messages (as much as possible).
    44  func ensureMapStrStr(m map[string]interface{}) (map[string]string, error) {
    45  	data, err := yaml.Marshal(m)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	ssm := make(map[string]string)
    51  	if err := yaml.Unmarshal(data, &ssm); err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	return ssm, nil
    56  }