structproto

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2023 License: MIT Imports: 5 Imported by: 5

README

structproto - StructPrototype

Synopsis

Binding struct from map
import (
  "fmt"
  "time"

  "github.com/Bofry/structproto"
  "github.com/Bofry/structproto/valuebinder"
)


type Character struct {
  Name        string    `demo:"*NAME"`
  Age         *int      `demo:"*AGE"`
  Alias       []string  `demo:"ALIAS"`
  DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
  Remark      string    `demo:"REMARK;note the character's personal favor"`
}

func main() {
  c := Character{}
  prototype, err := structproto.Prototypify(&c,
    &structproto.StructProtoResolveOption{
      TagName: "demo",
    })
  if err != nil {
    panic(err)
  }
  
  err = prototype.BindMap(map[string]interface{}{
    "NAME":          "luffy",
    "AGE":           "19",
    "ALIAS":         "lucy",
    "DATE_OF_BIRTH": "2020-05-05T00:00:00Z",
  }, valuebinder.BuildStringArgsBinder)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Name       : %q\n", model.Name)
  fmt.Printf("Age        : %d\n", *model.Age)
  fmt.Printf("Alias      : %q\n", model.Alias)
  fmt.Printf("DateOfBirth: %q\n", model.DateOfBirth)
  fmt.Printf("Remark     : %q\n", model.Remark)
  // Output:
  // Name       : "luffy"
  // Age        : 19
  // Alias      : ["lucy"]
  // DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
  // Remark     : ""
}
Binding struct from structproto.FieldValueMap
import (
  "fmt"
  "time"

  "github.com/Bofry/structproto"
  "github.com/Bofry/structproto/valuebinder"
)


type Character struct {
  Name        string    `demo:"*NAME"`
  Age         *int      `demo:"*AGE"`
  Alias       []string  `demo:"ALIAS"`
  DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
  Remark      string    `demo:"REMARK;note the character's personal favor"`
}

func main() {
  c := Character{}
  prototype, err := structproto.Prototypify(&c,
    &structproto.StructProtoResolveOption{
      TagName: "demo",
    })
  if err != nil {
    panic(err)
  }
  
  err = prototype.BindMap(structproto.FieldValueMap{
    "NAME":          "luffy",
    "AGE":           "19",
    "ALIAS":         "lucy",
    "DATE_OF_BIRTH": "2020-05-05T00:00:00Z",
  }, valuebinder.BuildStringArgsBinder)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Name       : %q\n", model.Name)
  fmt.Printf("Age        : %d\n", *model.Age)
  fmt.Printf("Alias      : %q\n", model.Alias)
  fmt.Printf("DateOfBirth: %q\n", model.DateOfBirth)
  fmt.Printf("Remark     : %q\n", model.Remark)
  // Output:
  // Name       : "luffy"
  // Age        : 19
  // Alias      : ["lucy"]
  // DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
  // Remark     : ""
}
Binding struct by FieldValueEntity slice
import (
  "fmt"
  "time"

  "github.com/Bofry/structproto"
  "github.com/Bofry/structproto/valuebinder"
)


type Character struct {
  Name        string    `demo:"*NAME"`
  Age         *int      `demo:"*AGE"`
  Alias       []string  `demo:"ALIAS"`
  DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
  Remark      string    `demo:"REMARK;note the character's personal favor"`
}

type FieldValue struct {
  Name  string
  Value string
}

func main() {
  c := Character{}
  prototype, err := structproto.Prototypify(&c,
    &structproto.StructProtoResolveOption{
      TagName: "demo",
    })
  if err != nil {
    panic(err)
  }
  
  err = prototype.BindFields([]structproto.FieldValueEntity{
		{Field: "NAME", Value: "luffy"},
		{Field: "AGE", Value: "19"},
		{Field: "ALIAS", Value: "lucy"},
		{Field: "DATE_OF_BIRTH", Value: "2020-05-05T00:00:00Z"},
  }, valuebinder.BuildStringArgsBinder)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Name       : %q\n", model.Name)
  fmt.Printf("Age        : %d\n", *model.Age)
  fmt.Printf("Alias      : %q\n", model.Alias)
  fmt.Printf("DateOfBirth: %q\n", model.DateOfBirth)
  fmt.Printf("Remark     : %q\n", model.Remark)
  // Output:
  // Name       : "luffy"
  // Age        : 19
  // Alias      : ["lucy"]
  // DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
  // Remark     : ""
}
Binding struct by channel iterator
import (
  "fmt"
  "time"

  "github.com/Bofry/structproto"
  "github.com/Bofry/structproto/valuebinder"
)


type Character struct {
  Name        string    `demo:"*NAME"`
  Age         *int      `demo:"*AGE"`
  Alias       []string  `demo:"ALIAS"`
  DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
  Remark      string    `demo:"REMARK;note the character's personal favor"`
}

type FieldValue struct {
  Name  string
  Value string
}

func main() {
  c := Character{}
  prototype, err := structproto.Prototypify(&c,
    &structproto.StructProtoResolveOption{
      TagName: "demo",
    })
  if err != nil {
    panic(err)
  }
  
  err = prototype.BindChan(func() <-chan structproto.FieldValueEntity {
    c := make(chan structproto.FieldValueEntity, 1)
    go func() {
      for _, v := range fieldValues {
        c <- v
      }
      close(c)
    }()
    return c
  }(), valuebinder.BuildStringArgsBinder)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Name       : %q\n", model.Name)
  fmt.Printf("Age        : %d\n", *model.Age)
  fmt.Printf("Alias      : %q\n", model.Alias)
  fmt.Printf("DateOfBirth: %q\n", model.DateOfBirth)
  fmt.Printf("Remark     : %q\n", model.Remark)
  // Output:
  // Name       : "luffy"
  // Age        : 19
  // Alias      : ["lucy"]
  // DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
  // Remark     : ""
}
Binding struct by custom structproto.Iterator
import (
  "fmt"
  "time"

  "github.com/Bofry/structproto"
  "github.com/Bofry/structproto/valuebinder"
)


type Character struct {
  Name        string    `demo:"*NAME"`
  Age         *int      `demo:"*AGE"`
  Alias       []string  `demo:"ALIAS"`
  DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
  Remark      string    `demo:"REMARK;note the character's personal favor"`
}

var _ structproto.Iterator = EntitySet(nil)

type EntitySet [][]string

func (set EntitySet) Iterate() <-chan structproto.FieldValueEntity {
	c := make(chan structproto.FieldValueEntity, 1)
	go func() {
		for _, v := range set {
			c <- structproto.FieldValueEntity{
				Field: v[0],
				Value: v[1],
			}
		}
		close(c)
	}()
	return c
}

func main() {
  c := Character{}
  prototype, err := structproto.Prototypify(&c,
    &structproto.StructProtoResolveOption{
      TagName: "demo",
    })
  if err != nil {
    panic(err)
  }
  
  err = prototype.BindIterator(EntitySet{
		{"NAME", "luffy"},
		{"AGE", "19"},
		{"ALIAS", "lucy"},
		{"DATE_OF_BIRTH", "2020-05-05T00:00:00Z"},
		{"NUMBERS", "5,12"},
	}, valuebinder.BuildStringArgsBinder)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Name       : %q\n", model.Name)
  fmt.Printf("Age        : %d\n", *model.Age)
  fmt.Printf("Alias      : %q\n", model.Alias)
  fmt.Printf("DateOfBirth: %q\n", model.DateOfBirth)
  fmt.Printf("Remark     : %q\n", model.Remark)
  // Output:
  // Name       : "luffy"
  // Age        : 19
  // Alias      : ["lucy"]
  // DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
  // Remark     : ""
}
Binding struct by custom StructBinder
import (
  "fmt"
  "time"

  "github.com/Bofry/structproto"
  "github.com/Bofry/structproto/valuebinder"
)


type Character struct {
  Name        string    `demo:"*NAME"`
  Age         *int      `demo:"*AGE"`
  Alias       []string  `demo:"ALIAS"`
  DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
  Remark      string    `demo:"REMARK;note the character's personal favor"`
}

type MapBinder struct {
  values map[string]string
}

func (b *MapBinder) Init(context *StructProtoContext) error {
  return nil
}

func (b *MapBinder) Bind(field FieldInfo, rv reflect.Value) error {
  name := field.Name()
  if v, ok := b.values[name]; ok {
    return valuebinder.StringArgsBinder(rv).Bind(v)
  }
  return nil
}

func (b *MapBinder) Deinit(context *StructProtoContext) error {
  // validate missing required fields
  return context.CheckIfMissingRequiredFields(func() <-chan string {
    c := make(chan string)
    go func() {
      for k := range b.values {
        c <- k
      }
      close(c)
    }()
    return c
  })
}

func main() {
  c := Character{}
  prototype, err := structproto.Prototypify(&c,
    &structproto.StructProtoResolveOption{
      TagName: "demo",
    })
  if err != nil {
    panic(err)
  }
  
  err = prototype.Bind(binder, valuebinder.BuildStringArgsBinder)
  if err != nil {
    panic(err)
  }
  fmt.Printf("Name       : %q\n", model.Name)
  fmt.Printf("Age        : %d\n", *model.Age)
  fmt.Printf("Alias      : %q\n", model.Alias)
  fmt.Printf("DateOfBirth: %q\n", model.DateOfBirth)
  fmt.Printf("Remark     : %q\n", model.Remark)
  // Output:
  // Name       : "luffy"
  // Age        : 19
  // Alias      : ["lucy"]
  // DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
  // Remark     : ""
}

Documentation

Index

Examples

Constants

View Source
const (
	RequiredFlag = common.RequiredFlag
	BlankFlag    = common.BlankFlag
)

Variables

This section is empty.

Functions

This section is empty.

Types

type FieldBindingError

type FieldBindingError struct {
	Field string
	Value interface{}
	Err   error
}

func (*FieldBindingError) Error

func (e *FieldBindingError) Error() string

func (*FieldBindingError) Unwrap

func (e *FieldBindingError) Unwrap() error

Unwrap returns the underlying error.

type FieldFlagSet

type FieldFlagSet []string

type FieldInfo

type FieldInfo interface {
	IDName() string
	Name() string
	Desc() string
	Index() int
	FindFlag(predicate func(v string) bool) bool
	HasFlag(v string) bool
	Tag() reflect.StructTag
}

type FieldInfoImpl

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

func (*FieldInfoImpl) Desc

func (f *FieldInfoImpl) Desc() string

Desc implements FieldInfo.

func (*FieldInfoImpl) FindFlag

func (f *FieldInfoImpl) FindFlag(predicate func(v string) bool) bool

FindFlag implements FieldInfo.

func (*FieldInfoImpl) HasFlag

func (f *FieldInfoImpl) HasFlag(v string) bool

HasFlag implements FieldInfo.

func (*FieldInfoImpl) IDName

func (f *FieldInfoImpl) IDName() string

IDName implements FieldInfo.

func (*FieldInfoImpl) Index

func (f *FieldInfoImpl) Index() int

Index implements FieldInfo.

func (*FieldInfoImpl) Name

func (f *FieldInfoImpl) Name() string

Name implements FieldInfo.

func (*FieldInfoImpl) Tag

func (f *FieldInfoImpl) Tag() reflect.StructTag

Tag implements FieldInfo.

type FieldValueEntity

type FieldValueEntity struct {
	Field string
	Value interface{}
}

type FieldValueMap

type FieldValueMap map[string]interface{}
Example
package main

import (
	"fmt"
	"time"

	"github.com/Bofry/structproto"
	"github.com/Bofry/structproto/valuebinder"
)

func main() {
	s := struct {
		Name        string    `demo:"*NAME"`
		Age         *int      `demo:"*AGE"`
		Alias       []string  `demo:"ALIAS"`
		DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
		Remark      string    `demo:"REMARK;note the character's personal favor"`
	}{}
	prototype, err := structproto.Prototypify(&s,
		&structproto.StructProtoResolveOption{
			TagName: "demo",
		})
	if err != nil {
		panic(err)
	}

	err = prototype.BindMap(structproto.FieldValueMap{
		"NAME":          "luffy",
		"AGE":           "19",
		"ALIAS":         "lucy",
		"DATE_OF_BIRTH": "2020-05-05T00:00:00Z",
	}, valuebinder.BuildStringBinder)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Name       : %q\n", s.Name)
	fmt.Printf("Age        : %d\n", *s.Age)
	fmt.Printf("Alias      : %q\n", s.Alias)
	fmt.Printf("DateOfBirth: %q\n", s.DateOfBirth)
	fmt.Printf("Remark     : %q\n", s.Remark)
}
Output:

Name       : "luffy"
Age        : 19
Alias      : ["lucy"]
DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
Remark     : ""

func (FieldValueMap) Iterate

func (values FieldValueMap) Iterate() <-chan FieldValueEntity

type FunctionStructBinder added in v0.2.1

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

func (*FunctionStructBinder) Bind added in v0.2.1

func (binder *FunctionStructBinder) Bind(field FieldInfo, rv reflect.Value) error

Bind implements StructBinder.

func (*FunctionStructBinder) Deinit added in v0.2.1

func (binder *FunctionStructBinder) Deinit(context *StructProtoContext) error

Deinit implements StructBinder.

func (*FunctionStructBinder) Init added in v0.2.1

func (binder *FunctionStructBinder) Init(context *StructProtoContext) error

Init implements StructBinder.

type Iterator

type Iterator interface {
	Iterate() <-chan FieldValueEntity
}

type MissingRequiredFieldError

type MissingRequiredFieldError struct {
	Field string
	Err   error
}

A MissingRequiredFieldError represents an error when the required fields cannot be binded or missing.

func (*MissingRequiredFieldError) Error

func (e *MissingRequiredFieldError) Error() string

func (*MissingRequiredFieldError) Unwrap

func (e *MissingRequiredFieldError) Unwrap() error

Unwrap returns the underlying error.

type Struct

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

func Prototypify

func Prototypify(target interface{}, option *StructProtoResolveOption) (*Struct, error)
Example
package main

import (
	"fmt"
	"time"

	"github.com/Bofry/structproto"
	"github.com/Bofry/structproto/valuebinder"
)

func main() {
	s := struct {
		Name        string    `demo:"*NAME"`
		Age         *int      `demo:"*AGE"`
		Alias       []string  `demo:"ALIAS"`
		DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
		Remark      string    `demo:"REMARK;note the character's personal favor"`
	}{}
	prototype, err := structproto.Prototypify(&s,
		&structproto.StructProtoResolveOption{
			TagName: "demo",
		})
	if err != nil {
		panic(err)
	}

	err = prototype.BindMap(map[string]interface{}{
		"NAME":          "luffy",
		"AGE":           "19",
		"ALIAS":         "lucy",
		"DATE_OF_BIRTH": "2020-05-05T00:00:00Z",
	}, valuebinder.BuildStringBinder)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Name       : %q\n", s.Name)
	fmt.Printf("Age        : %d\n", *s.Age)
	fmt.Printf("Alias      : %q\n", s.Alias)
	fmt.Printf("DateOfBirth: %q\n", s.DateOfBirth)
	fmt.Printf("Remark     : %q\n", s.Remark)
}
Output:

Name       : "luffy"
Age        : 19
Alias      : ["lucy"]
DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
Remark     : ""

func (*Struct) Bind

func (s *Struct) Bind(binder StructBinder) error

func (*Struct) BindChan

func (s *Struct) BindChan(iterator <-chan FieldValueEntity, buildValueBinder ValueBindProvider) error

func (*Struct) BindFields

func (s *Struct) BindFields(values []FieldValueEntity, buildValueBinder ValueBindProvider) error
Example
package main

import (
	"fmt"
	"time"

	"github.com/Bofry/structproto"
	"github.com/Bofry/structproto/valuebinder"
)

func main() {
	s := struct {
		Name        string    `demo:"*NAME"`
		Age         *int      `demo:"*AGE"`
		Alias       []string  `demo:"ALIAS"`
		DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
		Remark      string    `demo:"REMARK;note the character's personal favor"`
	}{}
	prototype, err := structproto.Prototypify(&s,
		&structproto.StructProtoResolveOption{
			TagName: "demo",
		})
	if err != nil {
		panic(err)
	}

	fieldValues := []structproto.FieldValueEntity{
		{Field: "NAME", Value: "luffy"},
		{Field: "AGE", Value: "19"},
		{Field: "ALIAS", Value: "lucy"},
		{Field: "DATE_OF_BIRTH", Value: "2020-05-05T00:00:00Z"},
	}

	err = prototype.BindFields(fieldValues, valuebinder.BuildStringBinder)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Name       : %q\n", s.Name)
	fmt.Printf("Age        : %d\n", *s.Age)
	fmt.Printf("Alias      : %q\n", s.Alias)
	fmt.Printf("DateOfBirth: %q\n", s.DateOfBirth)
	fmt.Printf("Remark     : %q\n", s.Remark)
}
Output:

Name       : "luffy"
Age        : 19
Alias      : ["lucy"]
DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
Remark     : ""

func (*Struct) BindIterator

func (s *Struct) BindIterator(iterator Iterator, buildValueBinder ValueBindProvider) error

func (*Struct) BindMap

func (s *Struct) BindMap(values map[string]interface{}, buildValueBinder ValueBindProvider) error
Example
package main

import (
	"fmt"
	"time"

	"github.com/Bofry/structproto"
	"github.com/Bofry/structproto/valuebinder"
)

func main() {
	s := struct {
		Name        string    `demo:"*NAME"`
		Age         *int      `demo:"*AGE"`
		Alias       []string  `demo:"ALIAS"`
		DateOfBirth time.Time `demo:"DATE_OF_BIRTH;the character's birth of date"`
		Remark      string    `demo:"REMARK;note the character's personal favor"`
	}{}
	prototype, err := structproto.Prototypify(&s,
		&structproto.StructProtoResolveOption{
			TagName: "demo",
		})
	if err != nil {
		panic(err)
	}

	err = prototype.BindMap(map[string]interface{}{
		"NAME":          "luffy",
		"AGE":           "19",
		"ALIAS":         "lucy",
		"DATE_OF_BIRTH": "2020-05-05T00:00:00Z",
	}, valuebinder.BuildStringBinder)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Name       : %q\n", s.Name)
	fmt.Printf("Age        : %d\n", *s.Age)
	fmt.Printf("Alias      : %q\n", s.Alias)
	fmt.Printf("DateOfBirth: %q\n", s.DateOfBirth)
	fmt.Printf("Remark     : %q\n", s.Remark)
}
Output:

Name       : "luffy"
Age        : 19
Alias      : ["lucy"]
DateOfBirth: "2020-05-05 00:00:00 +0000 UTC"
Remark     : ""

func (*Struct) Map added in v0.2.1

func (s *Struct) Map(mapper StructMapper) error

func (*Struct) Visit

func (s *Struct) Visit(visitor StructVisitor)

type StructBinder

type StructBinder interface {
	Init(context *StructProtoContext) error
	Bind(field FieldInfo, rv reflect.Value) error
	Deinit(context *StructProtoContext) error
}

type StructMapper added in v0.2.1

type StructMapper func(field FieldInfo, rv reflect.Value) error

type StructProtoContext

type StructProtoContext Struct

func (*StructProtoContext) CheckIfMissingRequiredFields

func (ctx *StructProtoContext) CheckIfMissingRequiredFields(visitFieldProc func() <-chan string) error

func (*StructProtoContext) Field

func (ctx *StructProtoContext) Field(name string) (v reflect.Value, ok bool)

func (*StructProtoContext) FieldInfo

func (ctx *StructProtoContext) FieldInfo(name string) FieldInfo

func (*StructProtoContext) FieldNames

func (ctx *StructProtoContext) FieldNames() []string

func (*StructProtoContext) IsRequired

func (ctx *StructProtoContext) IsRequired(name string) bool

func (*StructProtoContext) RequiredFields

func (ctx *StructProtoContext) RequiredFields() []string

func (*StructProtoContext) Target

func (ctx *StructProtoContext) Target() reflect.Value

type StructProtoResolveOption

type StructProtoResolveOption struct {
	TagName             string
	TagResolver         TagResolver
	CheckDuplicateNames bool
}

type StructProtoResolver

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

func NewStructProtoResolver

func NewStructProtoResolver(option *StructProtoResolveOption) *StructProtoResolver

func (*StructProtoResolver) Resolve

func (r *StructProtoResolver) Resolve(target interface{}) (*Struct, error)

type StructVisitor

type StructVisitor func(name string, rv reflect.Value, info FieldInfo)

type Tag

type Tag = common.Tag

type TagResolver

type TagResolver = common.TagResolver

type Unmarshaler added in v0.2.2

type Unmarshaler = common.Unmarshaler

type ValueBindProvider

type ValueBindProvider = common.ValueBindProvider

type ValueBinder

type ValueBinder = common.ValueBinder

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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