diff --git a/component/component.go b/component/component.go index fe45eea..30d7eef 100644 --- a/component/component.go +++ b/component/component.go @@ -4,6 +4,7 @@ package component import ( + "bytes" "context" "encoding/json" "errors" @@ -168,22 +169,47 @@ func (r *Reference[T]) UnmarshalJSON(data []byte) error { return json.Unmarshal(data, &r.uuid) } -// MarshalTOML marshals the referenced component UUID to TOML. -func (r Reference[T]) MarshalTOML() ([]byte, error) { +// MarshalText marshals the referenced component UUID to Text. +func (r Reference[T]) MarshalText() ([]byte, error) { // Use strconv.Quote to properly escape the string return []byte(strconv.Quote(r.uuid)), nil } -// UnmarshalTOML unmarshals the referenced component UUID from TOML. -func (r *Reference[T]) UnmarshalTOML(v any) error { - switch v := v.(type) { - case string: - r.uuid = v - case []byte: - r.uuid = string(v) +// UnmarshalText unmarshals the referenced component UUID from text. +func (r *Reference[T]) UnmarshalText(data []byte) error { + // Trim leading and trailing whitespace + data = bytes.TrimSpace(data) + + if len(data) < 2 { + return errors.New("invalid TOML string: too short") + } + + switch data[0] { + case '"': + // Basic string (double-quoted) + if data[len(data)-1] != '"' { + return errors.New("invalid TOML string: mismatched quotes") + } + s, err := strconv.Unquote(string(data)) + if err != nil { + return err + } + r.uuid = s + case '\'': + // Literal string (single-quoted) + if data[len(data)-1] != '\'' { + return errors.New("invalid TOML string: mismatched quotes") + } + uuid := string(data[1 : len(data)-1]) + // Check for illegal newlines in literal string + if strings.Contains(uuid, "\n") { + return errors.New("invalid TOML string: newlines not allowed in literal string") + } + r.uuid = uuid default: - return fmt.Errorf("invalid type %T for reference", v) + return errors.New("invalid TOML string: must start with ' or \"") } + return nil } diff --git a/types/types.go b/types/types.go index 6c74984..25f11cc 100644 --- a/types/types.go +++ b/types/types.go @@ -2,7 +2,6 @@ package types import ( - "encoding/json" "errors" "fmt" "strconv" @@ -54,7 +53,7 @@ func (o RawObject) MarshalJSON() ([]byte, error) { // It sets the Object's data to a copy of the input JSON data. func (o *RawObject) UnmarshalJSON(data []byte) error { if o == nil { - return errors.New("types.RawObject: UnmarshalTOML on nil pointer") + return errors.New("types.RawObject: UnmarshalJSON on nil pointer") } *o = append((*o)[0:0], data...) return nil @@ -70,18 +69,11 @@ func (o RawObject) MarshalTOML() ([]byte, error) { return o, nil } -// UnmarshalTOML implements the toml.Unmarshaler interface. +// UnmarshalText implements the toml.Unmarshaler interface. // It stores the raw TOML data without parsing it. -func (o *RawObject) UnmarshalTOML(v any) error { +func (o *RawObject) UnmarshalText(data []byte) error { if o == nil { - return errors.New("types.RawObject: UnmarshalTOML on nil pointer") - } - if v == nil { - return nil - } - data, err := json.Marshal(v) - if err != nil { - return err + return errors.New("types.RawObject: UnmarshalText on nil pointer") } *o = append((*o)[0:0], data...) return nil