From d19144903d40db39fe09b569ce6b44f0231cb768 Mon Sep 17 00:00:00 2001 From: Jean Niklas L'orange Date: Fri, 13 Oct 2017 22:19:04 +0200 Subject: [PATCH] Include RawMessage as a type, ref #8 --- type_test.go | 44 +++++++++++++++++++++++++++++++++++++++++++- types.go | 25 ++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/type_test.go b/type_test.go index b0d6ad1..abb17ca 100644 --- a/type_test.go +++ b/type_test.go @@ -1,4 +1,4 @@ -// Copyright 2015 Jean Niklas L'orange. All rights reserved. +// Copyright 2015-2017 Jean Niklas L'orange. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -96,3 +96,45 @@ func TestSpacing(t *testing.T) { t.Errorf("Expected result to be `{value \\a data \\b}`, but was `%s`", string(bs)) } } + +func TestMarshalRawMessageValue(t *testing.T) { + type Foo struct { + SomeVal string `edn:"some-val"` + Leftovers RawMessage + OtherVal string `edn:"other-val"` + } + + f := Foo{ + SomeVal: "egg", + Leftovers: []byte(`[\space #foo bar :baz 100 {#{} 1.0 "zap" nil}]`), + OtherVal: "spam", + } + bs, err := Marshal(f) + if err != nil { + t.Fatal(err) + } + if string(bs) != `{:some-val"egg":leftovers [\space #foo bar :baz 100{#{}1.0"zap"nil}] :other-val"spam"}` { + t.Errorf("Expected result to be `{:some-val\"egg\":leftovers [\\space #foo bar :baz 100{#{}1.0\"zap\"nil}] :other-val\"spam\"}`, but was `%s`", string(bs)) + } +} + +func TestUnmarshalRawMessageValue(t *testing.T) { + type Foo struct { + SomeVal string `edn:"some-val"` + Leftovers RawMessage + OtherVal string `edn:"other-val"` + } + const raw = `{ + :some-val"egg" + :leftovers [\space #foo bar :baz 100{#{} 1.0 "zap" nil}] + :other-val"spam" +}` + var f Foo + err := UnmarshalString(raw, &f) + if err != nil { + t.Fatal(err) + } + if string(f.Leftovers) != `[\space #foo bar :baz 100{#{} 1.0 "zap" nil}]` { + t.Errorf("Expected result to be `[\\space #foo bar :baz 100{#{} 1.0 \"zap\" nil}]`, but was `%s`", string(f.Leftovers)) + } +} diff --git a/types.go b/types.go index 793062e..6b0f1e9 100644 --- a/types.go +++ b/types.go @@ -1,4 +1,4 @@ -// Copyright 2015 Jean Niklas L'orange. All rights reserved. +// Copyright 2015-2017 Jean Niklas L'orange. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -7,9 +7,32 @@ package edn import ( "bufio" "bytes" + "errors" "fmt" ) +// RawMessage is a raw encoded, but valid, EDN value. It implements Marshaler +// and Unmarshaler and can be used to delay EDN decoding or precompute an EDN +// encoding. +type RawMessage []byte + +// MarshalEDN returns m as the EDN encoding of m. +func (m RawMessage) MarshalEDN() ([]byte, error) { + if m == nil { + return []byte("nil"), nil + } + return m, nil +} + +// UnmarshalEDN sets *m to a copy of data. +func (m *RawMessage) UnmarshalEDN(data []byte) error { + if m == nil { + return errors.New("edn.RawMessage: UnmarshalEDN on nil pointer") + } + *m = append((*m)[0:0], data...) + return nil +} + // A Keyword is an EDN keyword without : prepended in front. type Keyword string