From 3bfdae6b5c5fe206782572414b8e5aa61965e8d8 Mon Sep 17 00:00:00 2001 From: Patrick O'brien Date: Sat, 12 Nov 2016 10:25:07 +1000 Subject: [PATCH] Add boil.Byte type --- types/byte.go | 61 ++++++++++++++++++++++++++++++++++++++ types/byte_test.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++ types/json.go | 4 +-- 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 types/byte.go create mode 100644 types/byte_test.go diff --git a/types/byte.go b/types/byte.go new file mode 100644 index 0000000..3b4cce7 --- /dev/null +++ b/types/byte.go @@ -0,0 +1,61 @@ +package types + +import ( + "database/sql/driver" + "encoding/json" + "errors" +) + +// Byte is an alias for byte. +// Byte implements Marshal and Unmarshal. +type Byte byte + +// String output your byte. +func (b Byte) String() string { + return string(b) +} + +// UnmarshalJSON sets *b to a copy of data. +func (b *Byte) UnmarshalJSON(data []byte) error { + if b == nil { + return errors.New("json: unmarshal json on nil pointer to byte") + } + + var x string + if err := json.Unmarshal(data, &x); err != nil { + return err + } + + if len(x) > 1 { + return errors.New("json: cannot convert to byte, text len is greater than one") + } + + *b = Byte(x[0]) + return nil +} + +// MarshalJSON returns the JSON encoding of b. +func (b Byte) MarshalJSON() ([]byte, error) { + return []byte{'"', byte(b), '"'}, nil +} + +// Value returns b as a driver.Value. +func (b Byte) Value() (driver.Value, error) { + return []byte{byte(b)}, nil +} + +// Scan stores the src in *b. +func (b *Byte) Scan(src interface{}) error { + switch src.(type) { + case uint8: + *b = Byte(src.(uint8)) + case string: + *b = Byte(src.(string)[0]) + case []byte: + *b = Byte(src.([]byte)[0]) + default: + return errors.New("incompatible type for byte") + } + + return nil +} diff --git a/types/byte_test.go b/types/byte_test.go new file mode 100644 index 0000000..f3b81c9 --- /dev/null +++ b/types/byte_test.go @@ -0,0 +1,74 @@ +package types + +import ( + "bytes" + "encoding/json" + "testing" +) + +func TestByteString(t *testing.T) { + t.Parallel() + + b := Byte('b') + if b.String() != "b" { + t.Errorf("Expected %q, got %s", "b", b.String()) + } +} + +func TestByteUnmarshal(t *testing.T) { + t.Parallel() + + var b Byte + err := json.Unmarshal([]byte(`"b"`), &b) + if err != nil { + t.Error(err) + } + + if b != 'b' { + t.Errorf("Expected %q, got %s", "b", b) + } +} + +func TestByteMarshal(t *testing.T) { + t.Parallel() + + b := Byte('b') + res, err := json.Marshal(&b) + if err != nil { + t.Error(err) + } + + if !bytes.Equal(res, []byte(`"b"`)) { + t.Errorf("expected %s, got %s", `"b"`, b.String()) + } +} + +func TestByteValue(t *testing.T) { + t.Parallel() + + b := Byte('b') + v, err := b.Value() + if err != nil { + t.Error(err) + } + + if !bytes.Equal([]byte{byte(b)}, v.([]byte)) { + t.Errorf("byte mismatch, %v %v", b, v) + } +} + +func TestByteScan(t *testing.T) { + t.Parallel() + + var b Byte + + s := "b" + err := b.Scan(s) + if err != nil { + t.Error(err) + } + + if !bytes.Equal([]byte{byte(b)}, []byte{'b'}) { + t.Errorf("bad []byte: %#v ≠ %#v\n", b, "b") + } +} diff --git a/types/json.go b/types/json.go index b42e694..b9ac616 100644 --- a/types/json.go +++ b/types/json.go @@ -35,7 +35,7 @@ func (j *JSON) Marshal(obj interface{}) error { // UnmarshalJSON sets *j to a copy of data. func (j *JSON) UnmarshalJSON(data []byte) error { if j == nil { - return errors.New("JSON: UnmarshalJSON on nil pointer") + return errors.New("json: unmarshal json on nil pointer to json") } *j = append((*j)[0:0], data...) @@ -68,7 +68,7 @@ func (j *JSON) Scan(src interface{}) error { case []byte: source = src.([]byte) default: - return errors.New("Incompatible type for JSON") + return errors.New("incompatible type for json") } *j = JSON(append((*j)[0:0], source...))