kvs/kv/codec.go
2023-04-18 14:24:20 +08:00

117 lines
2.3 KiB
Go

package kv
import (
"github.com/tursom/GoCollections/exceptions"
"github.com/tursom/GoCollections/lang"
)
type (
Codec[V1, V2 any] interface {
lang.Object
encode(v2 V2) V1
decode(v1 V1) V2
}
codecStore[K1, K2, V1, V2 any] struct {
lang.BaseObject
kvs Store[K1, V1]
kCodec Codec[K1, K2]
vCodec Codec[V1, V2]
}
kCodecStore[K1, K2, V any] struct {
lang.BaseObject
kvs Store[K1, V]
codec Codec[K1, K2]
}
vCodecStore[K, V1, V2 any] struct {
lang.BaseObject
kvs Store[K, V1]
codec Codec[V1, V2]
}
invertCodec[V1, V2 any] struct {
lang.BaseObject
codec Codec[V2, V1]
}
)
func InvertCodec[V1, V2 any](codec Codec[V2, V1]) Codec[V1, V2] {
return &invertCodec[V1, V2]{codec: codec}
}
func CodecStore[K1, K2, V1, V2 any](
kvs Store[K1, V1],
kCodec Codec[K1, K2],
vCodec Codec[V1, V2],
) Store[K2, V2] {
return &codecStore[K1, K2, V1, V2]{
kvs: kvs,
kCodec: kCodec,
vCodec: vCodec,
}
}
func KCodecStore[K1, K2, V any](
kvs Store[K1, V],
codec Codec[K1, K2],
) Store[K2, V] {
return &kCodecStore[K1, K2, V]{
kvs: kvs,
codec: codec,
}
}
func VCodecStore[K, V1, V2 any](
kvs Store[K, V1],
codec Codec[V1, V2],
) Store[K, V2] {
return &vCodecStore[K, V1, V2]{
kvs: kvs,
codec: codec,
}
}
func (c *codecStore[K1, K2, V1, V2]) Put(key K2, value V2) exceptions.Exception {
return c.kvs.Put(c.kCodec.encode(key), c.vCodec.encode(value))
}
func (c *codecStore[K1, K2, V1, V2]) Get(key K2) (V2, exceptions.Exception) {
value, exception := c.kvs.Get(c.kCodec.encode(key))
if exception != nil {
return lang.Nil[V2](), exception
}
return c.vCodec.decode(value), nil
}
func (c *kCodecStore[K1, K2, V]) Put(key K2, value V) exceptions.Exception {
return c.kvs.Put(c.codec.encode(key), value)
}
func (c *kCodecStore[K1, K2, V]) Get(key K2) (V, exceptions.Exception) {
return c.kvs.Get(c.codec.encode(key))
}
func (c *vCodecStore[K, V1, V2]) Put(key K, value V2) exceptions.Exception {
return c.kvs.Put(key, c.codec.encode(value))
}
func (c *vCodecStore[K, V1, V2]) Get(key K) (V2, exceptions.Exception) {
get, exception := c.kvs.Get(key)
if exception != nil {
return lang.Nil[V2](), exception
}
return c.codec.decode(get), nil
}
func (i *invertCodec[V1, V2]) encode(v2 V2) V1 {
return i.codec.decode(v2)
}
func (i *invertCodec[V1, V2]) decode(v1 V1) V2 {
return i.codec.encode(v1)
}