Skip to content

foundation/serialization impl#1

Open
gbrennon wants to merge 11 commits intomainfrom
feat/foundation-package
Open

foundation/serialization impl#1
gbrennon wants to merge 11 commits intomainfrom
feat/foundation-package

Conversation

@gbrennon
Copy link
Contributor

@gbrennon gbrennon commented Feb 9, 2026

foundation/serialization implemented.

in the future maybe it will include impl of default serialization for other presentation layer protocols

- now README.md includes represents the current state of the proejct
- defined Serializable interface with ToData and FromData methods
- implemented JSONSerializable struct that uses JSON for serialization
- added tests for JSONSerializable to ensure correct serialization and deserialization
@gbrennon gbrennon self-assigned this Feb 9, 2026
Copilot AI review requested due to automatic review settings February 9, 2026 02:42
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new foundation/serialization capability by defining a Serializable interface and adding a JSON-based implementation, along with basic tests and repo-level developer tooling/docs (Makefile, .gitignore, README updates).

Changes:

  • Added Serializable interface and JSONSerializable implementation for JSON marshaling/unmarshaling.
  • Added a unit test covering JSON round-trip behavior.
  • Added README guidance plus Makefile targets for testing/coverage/release and a .gitignore for Go artifacts.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pkg/forging/foundation/serialization/serializable.go Introduces core Serializable interface.
pkg/forging/foundation/serialization/json_serializable.go Adds JSON-backed implementation of Serializable.
pkg/forging/foundation/serialization/json_serializable_test.go Adds JSON round-trip unit test.
README.md Documents the new serialization package and contributor workflow.
Makefile Adds test/coverage/check-coverage/release targets.
.gitignore Ignores Go build/test artifacts and editor files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +16 to +18
@cov=$(shell go tool cover -func=$(COVERAGE_FILE) | awk '/^total:/ {print $$3+0}') ; \
if [ $$(echo "$$cov < $(MIN_COVERAGE)" | bc) -eq 1 ]; then \
echo "FAIL: coverage below $(MIN_COVERAGE)% ($$cov%)"; exit 1; \
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check-coverage target depends on bc being installed (echo ... | bc). That tool isn’t available by default in some environments/CI images, which can make coverage checks fail unexpectedly. Consider doing the comparison in awk (or Go) to avoid external dependencies, or document bc as a prerequisite.

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +16
)

type JSONSerializable struct {
Value interface{}
}

func (j *JSONSerializable) ToData() ([]byte, error) {
return json.Marshal(j.Value)
}

func (j *JSONSerializable) FromData(data []byte) error {
return json.Unmarshal(data, &j.Value)
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FromData unmarshals into &j.Value (a *interface{}), which causes encoding/json to replace Value with generic map[string]any/[]any instead of populating the concrete destination. This breaks the intended round-trip and will make the test’s *testStruct type assertion fail. Unmarshal into the concrete destination stored in j.Value (and require it to be a non-nil pointer), or change the type to a generic JSONSerializable[T any] that holds *T so the destination type is explicit.

Suggested change
)
type JSONSerializable struct {
Value interface{}
}
func (j *JSONSerializable) ToData() ([]byte, error) {
return json.Marshal(j.Value)
}
func (j *JSONSerializable) FromData(data []byte) error {
return json.Unmarshal(data, &j.Value)
"fmt"
"reflect"
)
type JSONSerializable struct {
Value interface{}
}
func (j *JSONSerializable) ToData() ([]byte, error) {
return json.Marshal(j.Value)
}
func (j *JSONSerializable) FromData(data []byte) error {
if j == nil {
return fmt.Errorf("JSONSerializable receiver is nil")
}
if j.Value == nil {
return fmt.Errorf("JSONSerializable.Value must be a non-nil pointer; got <nil>")
}
v := reflect.ValueOf(j.Value)
if v.Kind() != reflect.Ptr || v.IsNil() {
return fmt.Errorf("JSONSerializable.Value must be a non-nil pointer; got %T", j.Value)
}
return json.Unmarshal(data, j.Value)

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,17 @@
package foundation
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Package name is foundation even though the folder path is foundation/serialization. This makes the public API awkward to consume (import path ends in serialization but code is referenced as foundation.JSONSerializable). Align package name with the directory (e.g., package serialization) or move the code under a foundation directory that matches the package name.

Suggested change
package foundation
package serialization

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +31
"testing"
)

type testStruct struct {
Name string
Age int
}

func TestJSONSerializable_ToDataAndFromData(t *testing.T) {
original := &JSONSerializable{Value: testStruct{Name: "Alice", Age: 30}}
data, err := original.ToData()
if err != nil {
t.Fatalf("ToData failed: %v", err)
}

copy := &JSONSerializable{Value: &testStruct{}}
err = copy.FromData(data)
if err != nil {
t.Fatalf("FromData failed: %v", err)
}

result, ok := copy.Value.(*testStruct)
if !ok {
t.Fatalf("Type assertion failed")
}
if result.Name != "Alice" || result.Age != 30 {
t.Errorf("Expected Alice, 30; got %s, %d", result.Name, result.Age)
}
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file isn’t gofmt-formatted (spaces instead of tabs/standard formatting). Running gofmt (or ensuring the formatter runs in CI) will normalize indentation/import formatting and avoid noisy diffs later.

Suggested change
"testing"
)
type testStruct struct {
Name string
Age int
}
func TestJSONSerializable_ToDataAndFromData(t *testing.T) {
original := &JSONSerializable{Value: testStruct{Name: "Alice", Age: 30}}
data, err := original.ToData()
if err != nil {
t.Fatalf("ToData failed: %v", err)
}
copy := &JSONSerializable{Value: &testStruct{}}
err = copy.FromData(data)
if err != nil {
t.Fatalf("FromData failed: %v", err)
}
result, ok := copy.Value.(*testStruct)
if !ok {
t.Fatalf("Type assertion failed")
}
if result.Name != "Alice" || result.Age != 30 {
t.Errorf("Expected Alice, 30; got %s, %d", result.Name, result.Age)
}
"testing"
)
type testStruct struct {
Name string
Age int
}
func TestJSONSerializable_ToDataAndFromData(t *testing.T) {
original := &JSONSerializable{Value: testStruct{Name: "Alice", Age: 30}}
data, err := original.ToData()
if err != nil {
t.Fatalf("ToData failed: %v", err)
}
copy := &JSONSerializable{Value: &testStruct{}}
err = copy.FromData(data)
if err != nil {
t.Fatalf("FromData failed: %v", err)
}
result, ok := copy.Value.(*testStruct)
if !ok {
t.Fatalf("Type assertion failed")
}
if result.Name != "Alice" || result.Age != 30 {
t.Errorf("Expected Alice, 30; got %s, %d", result.Name, result.Age)
}

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +21
go test -coverprofile=$(COVERAGE_FILE) ./...
go tool cover -func=$(COVERAGE_FILE)
@cov=$(shell go tool cover -func=$(COVERAGE_FILE) | awk '/^total:/ {print $$3+0}') ; \
if [ $$(echo "$$cov < $(MIN_COVERAGE)" | bc) -eq 1 ]; then \
echo "FAIL: coverage below $(MIN_COVERAGE)% ($$cov%)"; exit 1; \
else \
echo "PASS: coverage is $$cov%"; \
fi
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In check-coverage, cov=$(shell ...) is evaluated by make during recipe expansion, before the preceding go test -coverprofile=... line generates coverage.out. This can result in go tool cover running against a missing/stale file and makes the target unreliable. Compute cov using shell command substitution ($$(...)) inside the recipe after generating the coverage file.

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +28
release:
git tag v$(VERSION)
git push origin v$(VERSION)
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make release will happily run with an empty VERSION, creating/pushing a v tag, and it always pushes directly to origin. Add guards to require VERSION to be set/valid (and ideally ensure a clean working tree), and consider using an annotated tag (git tag -a) to reduce accidental releases.

Copilot uses AI. Check for mistakes.
gbrennon and others added 6 commits February 9, 2026 00:10
- added a new section in the README.md to document the release workflow, including prerequisites, steps for determining the next version, and automating the release process using scripts. This will help maintainers and contributors understand how to manage releases effectively and ensure consistency in versioning and changelog generation.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link

Copilot AI commented Feb 9, 2026

@gbrennon I've opened a new pull request, #2, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants