Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow to register models globally #4

Merged
merged 1 commit into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions examples/registry_singleton/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package main

import (
"bytes"
"encoding/binary"
"log"

"github.com/sonirico/parco"
)

type (
Animal struct {
Age uint8
Specie string
}

Flat struct {
Price float32
Address string
}
)

const (
AnimalType int = 0
FlatType = 1
)

func (a Animal) ParcoID() int {
return AnimalType
}

func (a Flat) ParcoID() int {
return FlatType
}

func main() {
animalBuilder := parco.Builder[Animal](parco.ObjectFactory[Animal]()).
SmallVarchar(
func(a *Animal) string { return a.Specie },
func(a *Animal, specie string) { a.Specie = specie },
).
UInt8(
func(a *Animal) uint8 { return a.Age },
func(a *Animal, age uint8) { a.Age = age },
)

flatBuilder := parco.Builder[Flat](parco.ObjectFactory[Flat]()).
Float32(
binary.LittleEndian,
func(f *Flat) float32 { return f.Price },
func(f *Flat, price float32) { f.Price = price },
).
SmallVarchar(
func(f *Flat) string { return f.Address },
func(f *Flat, address string) { f.Address = address },
)

_ = parco.RegisterModel(AnimalType, animalBuilder)
_ = parco.RegisterModel(FlatType, flatBuilder)

buf := bytes.NewBuffer(nil)

_ = parco.CompileModel(Animal{Age: 10, Specie: "monkeys"}, buf)
_ = parco.CompileModel(Flat{Price: 42, Address: "Plaza mayor"}, buf)
_ = parco.CompileAnyModel(AnimalType, Animal{Age: 7, Specie: "felix catus"}, buf)

id, something, _ := parco.ParseModel(buf)
Print(id, something)
id, something, _ = parco.ParseModel(buf)
Print(id, something)
id, something, _ = parco.ParseModel(buf)
Print(id, something)
}

func Print(id int, x any) {
switch id {
case AnimalType:
animal := x.(Animal)
log.Println("animal:", animal)
case FlatType:
flat := x.(Flat)
log.Println("flat", flat)
}
}
30 changes: 30 additions & 0 deletions parco_builder_multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"github.com/pkg/errors"
"io"
"sync/atomic"
)

type (
Expand Down Expand Up @@ -101,3 +102,32 @@ func (b *ModelMultiBuilder[T]) compile(id T, item any, w io.Writer) (err error)
err = c.CompileAny(item, w)
return
}

func newAtomicPtr[T comparable](builder *ModelMultiBuilder[T]) *atomic.Pointer[ModelMultiBuilder[T]] {
ptr := &atomic.Pointer[ModelMultiBuilder[T]]{}
ptr.Store(builder)
return ptr
}

var (
globalMultiBuilder = newAtomicPtr(MultiBuilder[int](UInt8Header()))
)

func RegisterModel(id int, builder builderAny) (err error) {
_, err = globalMultiBuilder.Load().Register(id, builder)
return
}

func CompileModel(item serializable[int], w io.Writer) (err error) {
err = globalMultiBuilder.Load().Compile(item, w)
return
}

func CompileAnyModel(id int, item any, w io.Writer) (err error) {
err = globalMultiBuilder.Load().CompileAny(id, item, w)
return
}

func ParseModel(r io.Reader) (int, any, error) {
return globalMultiBuilder.Load().Parse(r)
}