From ce0d70fa029f38f00bae2a0775a04107851d1f4c Mon Sep 17 00:00:00 2001
From: Leonard Lyubich <leonard@nspcc.ru>
Date: Fri, 13 Nov 2020 15:26:23 +0300
Subject: [PATCH] [#168] object: Implement binary/JSON encoders/decoders on
 ShortHeader

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
---
 v2/object/json.go         | 26 ++++++++++++++++++++++++++
 v2/object/json_test.go    | 20 ++++++++++++++++++++
 v2/object/marshal.go      | 11 +++++++++++
 v2/object/marshal_test.go |  6 ++----
 4 files changed, 59 insertions(+), 4 deletions(-)
 create mode 100644 v2/object/json.go
 create mode 100644 v2/object/json_test.go

diff --git a/v2/object/json.go b/v2/object/json.go
new file mode 100644
index 0000000..8038523
--- /dev/null
+++ b/v2/object/json.go
@@ -0,0 +1,26 @@
+package object
+
+import (
+	object "github.com/nspcc-dev/neofs-api-go/v2/object/grpc"
+	"google.golang.org/protobuf/encoding/protojson"
+)
+
+func (h *ShortHeader) MarshalJSON() ([]byte, error) {
+	return protojson.MarshalOptions{
+		EmitUnpopulated: true,
+	}.Marshal(
+		ShortHeaderToGRPCMessage(h),
+	)
+}
+
+func (h *ShortHeader) UnmarshalJSON(data []byte) error {
+	msg := new(object.ShortHeader)
+
+	if err := protojson.Unmarshal(data, msg); err != nil {
+		return err
+	}
+
+	*h = *ShortHeaderFromGRPCMessage(msg)
+
+	return nil
+}
diff --git a/v2/object/json_test.go b/v2/object/json_test.go
new file mode 100644
index 0000000..51d0aee
--- /dev/null
+++ b/v2/object/json_test.go
@@ -0,0 +1,20 @@
+package object_test
+
+import (
+	"testing"
+
+	"github.com/nspcc-dev/neofs-api-go/v2/object"
+	"github.com/stretchr/testify/require"
+)
+
+func TestShortHeaderJSON(t *testing.T) {
+	h := generateShortHeader("id")
+
+	data, err := h.MarshalJSON()
+	require.NoError(t, err)
+
+	h2 := new(object.ShortHeader)
+	require.NoError(t, h2.UnmarshalJSON(data))
+
+	require.Equal(t, h, h2)
+}
diff --git a/v2/object/marshal.go b/v2/object/marshal.go
index 43d4749..5e080c9 100644
--- a/v2/object/marshal.go
+++ b/v2/object/marshal.go
@@ -162,6 +162,17 @@ func (h *ShortHeader) StableSize() (size int) {
 	return size
 }
 
+func (h *ShortHeader) Unmarshal(data []byte) error {
+	m := new(object.ShortHeader)
+	if err := goproto.Unmarshal(data, m); err != nil {
+		return err
+	}
+
+	*h = *ShortHeaderFromGRPCMessage(m)
+
+	return nil
+}
+
 func (a *Attribute) StableMarshal(buf []byte) ([]byte, error) {
 	if a == nil {
 		return []byte{}, nil
diff --git a/v2/object/marshal_test.go b/v2/object/marshal_test.go
index 616c3c1..505c6b1 100644
--- a/v2/object/marshal_test.go
+++ b/v2/object/marshal_test.go
@@ -15,16 +15,14 @@ import (
 
 func TestShortHeader_StableMarshal(t *testing.T) {
 	hdrFrom := generateShortHeader("Owner ID")
-	transport := new(grpc.ShortHeader)
 
 	t.Run("non empty", func(t *testing.T) {
 		wire, err := hdrFrom.StableMarshal(nil)
 		require.NoError(t, err)
 
-		err = goproto.Unmarshal(wire, transport)
-		require.NoError(t, err)
+		hdrTo := new(object.ShortHeader)
+		require.NoError(t, hdrTo.Unmarshal(wire))
 
-		hdrTo := object.ShortHeaderFromGRPCMessage(transport)
 		require.Equal(t, hdrFrom, hdrTo)
 	})
 }