poly

package module
v0.0.0-...-b4967ac Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2025 License: MIT Imports: 6 Imported by: 0

README

Poly

Poly is a Go library for handling polymorphic JSON serialization and deserialization. It allows you to register interfaces and their implementations, then automatically sets discriminant fields during marshaling and creates appropriate concrete types during unmarshaling.

Features

  • Automatic discriminant field handling for JSON marshaling/unmarshaling
  • Support for nested structures and slices
  • Comprehensive error handling and validation
  • Easy registration of interfaces and implementations

Installation

go get github.com/reyoung/poly

Usage

Basic Example
package main

import (
    "encoding/json"
    "fmt"
    "github.com/reyoung/poly"
)

// Define an interface
type Shape interface{}

// Implement the interface with concrete types
type Circle struct {
    Type   string  `json:"type"`
    Radius float64 `json:"radius"`
}

type Rect struct {
    Type   string  `json:"type"`
    Width  float64 `json:"width"`
    Height float64 `json:"height"`
}

// Define a struct that uses the interface
type Request struct {
    Shape Shape `json:"shape"`
}

func main() {
    // Create a poly instance
    var p poly.Poly
    
    // Register the interface
    p.RegisterInterface((*Shape)(nil), "type", func(message json.RawMessage) (any, error) {
        var str string
        if err := json.Unmarshal(message, &str); err != nil {
            return nil, err
        }
        return str, nil
    })
    
    // Register the implementations
    p.RegisterStruct((*Shape)(nil), (*Circle)(nil), "circle")
    p.RegisterStruct((*Shape)(nil), (*Rect)(nil), "rect")
    
    // Marshal example
    req := &Request{
        Shape: &Circle{Radius: 10},
    }
    p.BeforeMarshalJSON(req)
    buf, _ := json.Marshal(req)
    fmt.Println(string(buf)) // {"shape":{"type":"circle","radius":10}}
    
    // Unmarshal example
    req2 := &Request{}
    buf2 := []byte(`{"shape":{"type":"rect","width":5,"height":3}}`)
    p.BeforeUnmarshalJSON(req2, buf2)
    json.Unmarshal(buf2, &req2)
    rect, _ := req2.Shape.(*Rect)
    fmt.Printf("%+v\n", rect) // &{Type:rect Width:5 Height:3}
}
Working with Slices

The library also supports slices of interface types:

type RequestWithSlice struct {
    Shapes []Shape `json:"shapes"`
}

req := &RequestWithSlice{
    Shapes: []Shape{
        &Circle{Radius: 10},
        &Rect{Width: 5, Height: 3},
    },
}

API Reference

Poly

The main type for managing interface registrations.

Methods
  • RegisterInterface(iFacePtr any, discriminantFieldName string, discriminantFieldParser func(json.RawMessage) (any, error)) error Registers an interface type for polymorphic handling.

  • RegisterStruct(iFacePtr any, structPtr any, value any) error Registers a struct implementation for an interface.

  • BeforeMarshalJSON(ptr any) error Prepares a value for JSON marshaling by setting discriminant fields.

  • BeforeUnmarshalJSON(ptr any, buf []byte) error Prepares a value for JSON unmarshaling by creating appropriate concrete types.

License

MIT

Documentation

Overview

Package poly provides utilities for handling polymorphic JSON serialization and deserialization. It allows registering interfaces and their implementations, then automatically sets discriminant fields during marshaling and creates appropriate concrete types during unmarshaling.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Poly

type Poly struct {
	// contains filtered or unexported fields
}

Poly manages the registration of interfaces and their implementations for polymorphic JSON handling

func (*Poly) BeforeMarshalJSON

func (p *Poly) BeforeMarshalJSON(ptr any, strict bool) error

BeforeMarshalJSON prepares a value for JSON marshaling by setting discriminant fields Call this before json.Marshal to ensure interface implementations are correctly tagged

func (*Poly) BeforeUnmarshalJSON

func (p *Poly) BeforeUnmarshalJSON(buf []byte, ptr any, strict bool) error

BeforeUnmarshalJSON prepares a value for JSON unmarshaling by creating appropriate concrete types Call this before json.Unmarshal to ensure interface fields get the correct concrete implementations ptr: pointer to the value to populate buf: the JSON bytes to parse

func (*Poly) RegisterInterface

func (p *Poly) RegisterInterface(
	iFacePtr any,
	discriminantFieldName string) error

RegisterInterface registers an interface type for polymorphic handling iFacePtr: a pointer to the interface type (e.g., (*Shape)(nil)) discriminantFieldName: the JSON field name used to distinguish implementations (e.g., "type") discriminantFieldParser: a function to parse the discriminant field value from raw JSON

func (*Poly) RegisterStruct

func (p *Poly) RegisterStruct(
	iFacePtr any,
	structPtr any,
	value any) error

RegisterStruct registers a struct implementation for an interface iFacePtr: a pointer to the interface type (e.g., (*Shape)(nil)) structPtr: a pointer to the struct type (e.g., (*Circle)(nil)) value: the discriminant value for this struct (e.g., "circle")

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL