Skip to content

Commit

Permalink
Removed write quote in marshal to allow write other types than strings
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas Baldoni committed Feb 9, 2022
1 parent 4272474 commit 62ff2d2
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 1 deletion.
158 changes: 158 additions & 0 deletions custom_marshaler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package toml_test

import (
"bytes"
"errors"
"fmt"
"github.com/BurntSushi/toml"
"strconv"
"strings"
"testing"
)

// Test for hotfix-341
func TestCustomEncode(t *testing.T) {

var enum = Enum(OtherValue)

outer := Outer{
String: &InnerString{value: "value"},
Int: &InnerInt{value: 10},
Bool: &InnerBool{value: true},
Enum: &enum,
}

var buf bytes.Buffer
err := toml.NewEncoder(&buf).Encode(outer)
if err != nil {
t.Errorf("Encode failed: %s", err)
}

have := strings.TrimSpace(buf.String())
want := strings.TrimSpace("String = \"value\"\nInt = 10\nBool = true\nEnum = \"OTHER_VALUE\"\n")
if want != have {
t.Errorf("\nhave:\n%s\nwant:\n%s\n", have, want)
}
}

// Test for hotfix-341
func TestCustomDecode(t *testing.T) {

const testToml = "Bool = true\nString = \"test\"\nInt = 10\nEnum = \"OTHER_VALUE\""

outer := Outer{}
_, err := toml.Decode(testToml, &outer)

if err != nil {
t.Errorf("Decode failed: %s", err)
}
if outer.String.value != "test" {
t.Errorf("\nhave:\n%s\nwant:\n%s\n", outer.String.value, "test")
}
if outer.Bool.value != true {
t.Errorf("\nhave:\n%v\nwant:\n%v\n", outer.Bool.value, true)
}
if outer.Int.value != 10 {
t.Errorf("\nhave:\n%v\nwant:\n%v\n", outer.Int.value, 10)
}
if *outer.Enum != OtherValue {
t.Errorf("\nhave:\n%v\nwant:\n%v\n", outer.Enum, OtherValue)
}
}

/* Implementing MarshalTOML and UnmarshalTOML structs
An useful use could be to map a TOML value to an internal value, like emuns.
*/

type Enum int

const (
NoValue Enum = iota
SomeValue
OtherValue
)

func (e *Enum) Value() string {
switch *e {
case SomeValue:
return "SOME_VALUE"
case OtherValue:
return "OTHER_VALUE"
case NoValue:
return ""
}
return ""
}

func (e *Enum) MarshalTOML() ([]byte, error) {
return []byte("\"" + e.Value() + "\""), nil
}

func (e *Enum) UnmarshalTOML(value interface{}) error {
sValue, ok := value.(string)
if !ok {
return fmt.Errorf("value %v is not a string type", value)
}
for _, enum := range []Enum{NoValue, SomeValue, OtherValue} {
if enum.Value() == sValue {
*e = enum
return nil
}
}
return errors.New("invalid enum value")
}

type InnerString struct {
value string
}

func (s *InnerString) MarshalTOML() ([]byte, error) {
return []byte("\"" + s.value + "\""), nil
}
func (s *InnerString) UnmarshalTOML(value interface{}) error {
sValue, ok := value.(string)
if !ok {
return fmt.Errorf("value %v is not a string type", value)
}
s.value = sValue
return nil
}

type InnerInt struct {
value int
}

func (i *InnerInt) MarshalTOML() ([]byte, error) {
return []byte(strconv.Itoa(i.value)), nil
}
func (i *InnerInt) UnmarshalTOML(value interface{}) error {
iValue, ok := value.(int64)
if !ok {
return fmt.Errorf("value %v is not a int type", value)
}
i.value = int(iValue)
return nil
}

type InnerBool struct {
value bool
}

func (b *InnerBool) MarshalTOML() ([]byte, error) {
return []byte(strconv.FormatBool(b.value)), nil
}
func (b *InnerBool) UnmarshalTOML(value interface{}) error {
bValue, ok := value.(bool)
if !ok {
return fmt.Errorf("value %v is not a bool type", value)
}
b.value = bValue
return nil
}

type Outer struct {
String *InnerString
Int *InnerInt
Bool *InnerBool
Enum *Enum
}
2 changes: 1 addition & 1 deletion encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func (enc *Encoder) eElement(rv reflect.Value) {
if err != nil {
encPanic(err)
}
enc.writeQuoted(string(s))
enc.w.Write(s)
return
case encoding.TextMarshaler:
s, err := v.MarshalText()
Expand Down

0 comments on commit 62ff2d2

Please sign in to comment.