From 5bbe46855eb0b787ed32b58109ec2facd2b36a27 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Mon, 15 Apr 2024 13:24:09 +0200 Subject: [PATCH] feat(collections): add `NewJSONValueCodec` (#19861) Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- collections/CHANGELOG.md | 21 ++++++++------- collections/json.go | 58 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 collections/json.go diff --git a/collections/CHANGELOG.md b/collections/CHANGELOG.md index a0633d328e9f..fda6ca900b30 100644 --- a/collections/CHANGELOG.md +++ b/collections/CHANGELOG.md @@ -33,19 +33,20 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -* [#19343](https://github.com/cosmos/cosmos-sdk/pull/19343) – Simplify IndexedMap creation by allowing to infer indexes through reflection. -* [#18933](https://github.com/cosmos/cosmos-sdk/pull/18933) – Add LookupMap implementation. It is basic wrapping of the standard Map methods but is not iterable. -* [#17656](https://github.com/cosmos/cosmos-sdk/pull/17656) – Introduces `Vec`, a collection type that allows to represent a growable array on top of a KVStore. +* [#19343](https://github.com/cosmos/cosmos-sdk/pull/19343) Simplify IndexedMap creation by allowing to infer indexes through reflection. +* [#18933](https://github.com/cosmos/cosmos-sdk/pull/18933) Add LookupMap implementation. It is basic wrapping of the standard Map methods but is not iterable. +* [#17656](https://github.com/cosmos/cosmos-sdk/pull/17656) Introduces `Vec`, a collection type that allows to represent a growable array on top of a KVStore. +* [#19861](https://github.com/cosmos/cosmos-sdk/pull/19861) Add `NewJSONValueCodec` value codec as an alternative for `codec.CollValue` from the SDK for non protobuf types. ## [v0.4.0](https://github.com/cosmos/cosmos-sdk/releases/tag/collections%2Fv0.4.0) ### Features -* [#17024](https://github.com/cosmos/cosmos-sdk/pull/17024) - Introduces `Triple`, a composite key with three keys. +* [#17024](https://github.com/cosmos/cosmos-sdk/pull/17024) Introduces `Triple`, a composite key with three keys. ### API Breaking -* [#17290](https://github.com/cosmos/cosmos-sdk/pull/17290) - Collections iteration methods (Iterate, Walk) will not error when the collection is empty. +* [#17290](https://github.com/cosmos/cosmos-sdk/pull/17290) Collections iteration methods (Iterate, Walk) will not error when the collection is empty. ### Improvements @@ -55,20 +56,20 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features -* [#16074](https://github.com/cosmos/cosmos-sdk/pull/16607) - Introduces `Clear` method for `Map` and `KeySet` +* [#16074](https://github.com/cosmos/cosmos-sdk/pull/16607) Introduces `Clear` method for `Map` and `KeySet` * [#16773](https://github.com/cosmos/cosmos-sdk/pull/16773) - * Adds `AltValueCodec` which provides a way to decode a value in two ways. - * Adds the possibility to specify an alternative way to decode the values of `KeySet`, `indexes.Multi`, `indexes.ReversePair`. + * Adds `AltValueCodec` which provides a way to decode a value in two ways. + * Adds the possibility to specify an alternative way to decode the values of `KeySet`, `indexes.Multi`, `indexes.ReversePair`. ## [v0.2.0](https://github.com/cosmos/cosmos-sdk/releases/tag/collections%2Fv0.2.0) ### Features -* [#16074](https://github.com/cosmos/cosmos-sdk/pull/16074) – Makes the generic Collection interface public, still highly unstable. +* [#16074](https://github.com/cosmos/cosmos-sdk/pull/16074) Makes the generic Collection interface public, still highly unstable. ### API Breaking -* [#16127](https://github.com/cosmos/cosmos-sdk/pull/16127) – In the `Walk` method the call back function being passed is allowed to error. +* [#16127](https://github.com/cosmos/cosmos-sdk/pull/16127) In the `Walk` method the call back function being passed is allowed to error. ## [v0.1.0](https://github.com/cosmos/cosmos-sdk/releases/tag/collections%2Fv0.1.0) diff --git a/collections/json.go b/collections/json.go new file mode 100644 index 000000000000..6b6866ecfbdc --- /dev/null +++ b/collections/json.go @@ -0,0 +1,58 @@ +package collections + +import ( + "encoding/json" + "fmt" + + "cosmossdk.io/collections/codec" +) + +func NewJSONValueCodec[T any]() codec.ValueCodec[T] { + return jsonValue[T]{ + typeName: fmt.Sprintf("%T", new(T)), + } +} + +type jsonValue[T any] struct { + typeName string +} + +// Decode implements codec.ValueCodec. +func (jsonValue[T]) Decode(b []byte) (T, error) { + var t T + if err := json.Unmarshal(b, &t); err != nil { + return t, err + } + + return t, nil +} + +// DecodeJSON implements codec.ValueCodec. +func (jsonValue[T]) DecodeJSON(b []byte) (T, error) { + var t T + if err := json.Unmarshal(b, &t); err != nil { + return t, err + } + + return t, nil +} + +// Encode implements codec.ValueCodec. +func (jsonValue[T]) Encode(value T) ([]byte, error) { + return json.Marshal(value) +} + +// EncodeJSON implements codec.ValueCodec. +func (jsonValue[T]) EncodeJSON(value T) ([]byte, error) { + return json.Marshal(value) +} + +// Stringify implements codec.ValueCodec. +func (jsonValue[T]) Stringify(value T) string { + return fmt.Sprintf("%v", value) +} + +// ValueType implements codec.ValueCodec. +func (jv jsonValue[T]) ValueType() string { + return fmt.Sprintf("json(%s)", jv.typeName) +}