我正在尝试创建一个自定义 yaml 编组器,因此引用的字符串会得到双引号,而不是单引号。
我有以下类型/方法(为简洁起见,进行了简化):
type SetFactTask struct {
Name string `yaml:"name"`
Module FactValue `yaml:"ansible.builtin.set_fact"`
}
type FactValue map[string]string
// playing around with various ways to force output to have double quotes, not embedded in single-quotes
func (f FactValue) MarshalYAML() (interface{}, error) {
sb := strings.Builder{}
for k, v := range f {
sb.WriteString(fmt.Sprintf(" %s:", k))
sb.Write([]byte(`"`))
sb.WriteString(v)
sb.Write([]byte(`"`))
}
return sb.String(), nil
}
如果我有这个代码:
foo := modules.SetFactTask{
Name: "foo",
Module: modules.FactValue{
"foo": "\"{{ somevar }}\"",
},
}
output, err := yaml.Marshal(foo)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", output)
我得到这个输出(foo 的值用单引号括起来):
name: foo
ansible.builtin.set_fact: ' foo:""{{ somevar }}""'
这就是我想要的:
name: foo
ansible.builtin.set_fact:
foo: "{{ somevar }}"
看起来我的 MarshalYAML 方法没有被调用。没有错误或任何东西。
yaml.Marshaller
接口定义了一个可以由类型实现的函数,并且它需要一个指针接收器。将代码更改为以下结果会导致 MarshalYAML
被调用为 FactValue
:
// playing around with various ways to force output to have double quotes, not embedded in single-quotes
func (f *FactValue) MarshalYAML() (interface{}, error) {
sb := strings.Builder{}
for k, v := range *f {
sb.WriteString(fmt.Sprintf(" %s:", k))
sb.Write([]byte(`"`))
sb.WriteString(v)
sb.Write([]byte(`"`))
}
return sb.String(), nil
}
在我的测试代码中,返回:
name: foo
ansible.builtin.set_fact:
foo: '"{{ somevar }}"'