From c31f9aa7045c4fd66b109d441ed5d6508842c650 Mon Sep 17 00:00:00 2001 From: ajiyoshi-vg Date: Fri, 7 Mar 2025 15:44:47 +0900 Subject: [PATCH 1/3] add codec.JSON --- chunkfile.go | 31 ++++++------------------------- codec/codec.go | 11 +++++++++++ codec/json.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 codec/codec.go create mode 100644 codec/json.go diff --git a/chunkfile.go b/chunkfile.go index 1117095..d883481 100644 --- a/chunkfile.go +++ b/chunkfile.go @@ -2,24 +2,27 @@ package external import ( "bufio" - "encoding/json" "errors" "io" "iter" "os" "slices" + + "github.com/ajiyoshi-vg/external/codec" ) type ChunkFile[T any] struct { data []T tmpFile *string length int + codec codec.Codec[T] } func NewChunkFile[T any](data []T) *ChunkFile[T] { return &ChunkFile[T]{ data: data, length: len(data), + codec: codec.JSON[T]{}, } } @@ -52,13 +55,7 @@ func (x *ChunkFile[T]) Store() error { func (x *ChunkFile[T]) store(w io.WriteCloser) error { buf := bufio.NewWriter(w) defer buf.Flush() - enc := json.NewEncoder(buf) - for _, v := range x.data { - if err := enc.Encode(v); err != nil { - return err - } - } - return nil + return x.codec.Encode(slices.Values(x.data), buf) } func (x *ChunkFile[T]) Restore() (iter.Seq[T], error) { @@ -69,21 +66,5 @@ func (x *ChunkFile[T]) Restore() (iter.Seq[T], error) { if err != nil { return nil, err } - return x.restore(tempFile), nil -} - -func (x *ChunkFile[T]) restore(r io.ReadCloser) iter.Seq[T] { - dec := json.NewDecoder(bufio.NewReader(r)) - return func(yield func(T) bool) { - defer r.Close() - for dec.More() { - var v T - if err := dec.Decode(&v); err != nil { - return - } - if !yield(v) { - return - } - } - } + return x.codec.Decode(tempFile), nil } diff --git a/codec/codec.go b/codec/codec.go new file mode 100644 index 0000000..1c14fd8 --- /dev/null +++ b/codec/codec.go @@ -0,0 +1,11 @@ +package codec + +import ( + "io" + "iter" +) + +type Codec[T any] interface { + Encode(seq iter.Seq[T], w io.Writer) error + Decode(r io.ReadCloser) iter.Seq[T] +} diff --git a/codec/json.go b/codec/json.go new file mode 100644 index 0000000..43785d7 --- /dev/null +++ b/codec/json.go @@ -0,0 +1,39 @@ +package codec + +import ( + "encoding/json" + "io" + "iter" + "log" +) + +type JSON[T any] struct{} + +var _ Codec[int] = (*JSON[int])(nil) + +func (JSON[T]) Encode(seq iter.Seq[T], w io.Writer) error { + enc := json.NewEncoder(w) + for x := range seq { + if err := enc.Encode(x); err != nil { + return err + } + } + return nil +} + +func (JSON[T]) Decode(r io.ReadCloser) iter.Seq[T] { + dec := json.NewDecoder(r) + return func(yield func(T) bool) { + defer r.Close() + for dec.More() { + var x T + if err := dec.Decode(&x); err != nil { + log.Printf("decode failed: %v", err) + return + } + if !yield(x) { + return + } + } + } +} From 3d2a6578e62e62b69b80c4210ed83c58e7d6ff3c Mon Sep 17 00:00:00 2001 From: ajiyoshi-vg Date: Fri, 7 Mar 2025 15:47:50 +0900 Subject: [PATCH 2/3] json_test.go --- codec/json_test.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 codec/json_test.go diff --git a/codec/json_test.go b/codec/json_test.go new file mode 100644 index 0000000..9d07fc8 --- /dev/null +++ b/codec/json_test.go @@ -0,0 +1,36 @@ +package codec + +import ( + "bytes" + "io" + "slices" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestJSON(t *testing.T) { + cases := map[string]struct { + input []int + expect []int + }{ + "normal": { + input: []int{1, 2, 3}, + expect: []int{1, 2, 3}, + }, + } + + for title, c := range cases { + t.Run(title, func(t *testing.T) { + codec := &JSON[int]{} + seq := slices.Values(c.input) + var b bytes.Buffer + err := codec.Encode(seq, &b) + assert.NoError(t, err) + + r := io.NopCloser(&b) + actual := slices.Collect(codec.Decode(r)) + assert.Equal(t, c.expect, actual) + }) + } +} From 0b47c4d90bf17caaf2849372e7b30a208dafc6a1 Mon Sep 17 00:00:00 2001 From: ajiyoshi-vg Date: Fri, 7 Mar 2025 16:08:43 +0900 Subject: [PATCH 3/3] go.mod --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0b443f3..dfa61d3 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -19,7 +19,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.20' + go-version-file: 'go.mod' - name: Build run: go build -v ./...