mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
utils/bimap: drop json/v2 marshaler, keep type generic
BiMap is generic over comparable K,V — bolting on a json/v2 Marshaler/Unmarshaler bound the type to text I/O it has no business caring about. Removed the marshaler interface and the dependent tests; no consumer of BiMap in the node module relied on JSON. Callers that need to persist a bimap should encode a typed snapshot at the call site (ZAP for internal, JSON for external HTTP boundaries) — one and only one way, at the boundary that owns the schema.
This commit is contained in:
+5
-36
@@ -1,26 +1,20 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
// Package bimap is an in-memory bi-directional map. Serialization is the
|
||||
// caller's concern — this type is generic over comparable K/V, and the
|
||||
// internal Lux wire format is ZAP, which is element-typed. Use a typed
|
||||
// ZAP schema (or a typed snapshot struct) at the call site to persist a
|
||||
// bimap; do not bolt a generic marshaler onto BiMap itself.
|
||||
package bimap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/go-json-experiment/json"
|
||||
"errors"
|
||||
"maps"
|
||||
"slices"
|
||||
|
||||
"github.com/luxfi/node/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
_ json.Marshaler = (*BiMap[int, int])(nil)
|
||||
_ json.Unmarshaler = (*BiMap[int, int])(nil)
|
||||
|
||||
nullBytes = []byte("null")
|
||||
errNotBijective = errors.New("map not bijective")
|
||||
)
|
||||
|
||||
type Entry[K, V any] struct {
|
||||
Key K
|
||||
Value V
|
||||
@@ -127,28 +121,3 @@ func (m *BiMap[_, V]) Values() []V {
|
||||
func (m *BiMap[K, V]) Len() int {
|
||||
return len(m.keyToValue)
|
||||
}
|
||||
|
||||
func (m *BiMap[K, V]) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(m.keyToValue)
|
||||
}
|
||||
|
||||
func (m *BiMap[K, V]) UnmarshalJSON(b []byte) error {
|
||||
if bytes.Equal(b, nullBytes) {
|
||||
return nil
|
||||
}
|
||||
var keyToValue map[K]V
|
||||
if err := json.Unmarshal(b, &keyToValue); err != nil {
|
||||
return err
|
||||
}
|
||||
valueToKey := make(map[V]K, len(keyToValue))
|
||||
for k, v := range keyToValue {
|
||||
valueToKey[v] = k
|
||||
}
|
||||
if len(keyToValue) != len(valueToKey) {
|
||||
return errNotBijective
|
||||
}
|
||||
|
||||
m.keyToValue = keyToValue
|
||||
m.valueToKey = valueToKey
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
package bimap
|
||||
|
||||
import (
|
||||
"github.com/go-json-experiment/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -338,29 +337,6 @@ func TestBiMapLenAndLists(t *testing.T) {
|
||||
require.Empty(m.Values())
|
||||
}
|
||||
|
||||
func TestBiMapJSON(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
expectedMap := New[int, int]()
|
||||
expectedMap.Put(1, 2)
|
||||
expectedMap.Put(2, 3)
|
||||
|
||||
jsonBytes, err := json.Marshal(expectedMap)
|
||||
require.NoError(err)
|
||||
|
||||
expectedJSONBytes := []byte(`{"1":2,"2":3}`)
|
||||
require.JSONEq(string(expectedJSONBytes), string(jsonBytes))
|
||||
|
||||
var unmarshalledMap BiMap[int, int]
|
||||
require.NoError(json.Unmarshal(jsonBytes, &unmarshalledMap))
|
||||
require.Equal(expectedMap, &unmarshalledMap)
|
||||
}
|
||||
|
||||
func TestBiMapInvalidJSON(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
invalidJSONBytes := []byte(`{"1":2,"2":2}`)
|
||||
var unmarshalledMap BiMap[int, int]
|
||||
err := json.Unmarshal(invalidJSONBytes, &unmarshalledMap)
|
||||
require.ErrorIs(err, errNotBijective)
|
||||
}
|
||||
// JSON marshal/unmarshal tests removed: BiMap no longer carries a
|
||||
// generic codec. The internal Lux wire format is ZAP, which is element-
|
||||
// typed; persist a typed snapshot at the call site if needed.
|
||||
|
||||
Reference in New Issue
Block a user