Documentation
¶
Index ¶
- Constants
- func Map[To, From any](ctx context.Context, from From) (_ To, returnErr error)
- func MustMap[To, From any](ctx context.Context, from From) To
- func Register[From, To any](mapTo mapFunc[From, To], mapFrom mapFunc[To, From]) func()
- type ErrMustMap
- type MK
- type MP
- type Mapper
- type MapperTo
- type Mapping
- func (m Mapping[ENT, DTO]) MapFromiDTOPtr(ctx context.Context, dtoPtr any) (ENT, error)
- func (m Mapping[ENT, DTO]) MapToDTO(ctx context.Context, ent ENT) (DTO, error)
- func (m Mapping[ENT, DTO]) MapToENT(ctx context.Context, dto DTO) (ENT, error)
- func (m Mapping[ENT, DTO]) MapToiDTO(ctx context.Context, ent ENT) (any, error)
- func (m Mapping[ENT, DTO]) NewiDTO() any
- type P
Examples ¶
Constants ¶
const ErrNoMapping errorkit.Error = "[dtokit] missing mapping"
Variables ¶
This section is empty.
Functions ¶
func Map ¶
Example ¶
package main import ( "context" "strconv" "go.llib.dev/frameless/pkg/dtokit" ) func main() { var _ = dtokit.Register[Ent, EntDTO]( // only once at the global level EntMapping{}.ToDTO, EntMapping{}.ToEnt, ) var ( ctx = context.Background() ent = Ent{V: 42, N: 12} ) dto, err := dtokit.Map[EntDTO](ctx, ent) if err != nil { panic(err) } gotEnt, err := dtokit.Map[Ent](ctx, dto) if err != nil { panic(err) } _ = gotEnt == ent // true } type Ent struct { V int N int } type EntDTO struct { V string `json:"v"` N int `json:"n"` } type EntMapping struct{} func (EntMapping) ToDTO(ctx context.Context, ent Ent) (EntDTO, error) { return EntDTO{V: strconv.Itoa(ent.V), N: ent.N}, nil } func (EntMapping) ToEnt(ctx context.Context, dto EntDTO) (Ent, error) { v, err := strconv.Atoi(dto.V) if err != nil { return Ent{}, err } return Ent{V: v, N: dto.N}, nil }
Example (SliceSyntaxSugar) ¶
package main import ( "context" "strconv" "go.llib.dev/frameless/pkg/dtokit" ) func main() { var _ = dtokit.Register[Ent, EntDTO]( // only once at the global level EntMapping{}.ToDTO, EntMapping{}.ToEnt, ) var ( ctx = context.Background() ents = []Ent{{V: 42, N: 12}} ) // all individual value will be mapped res, err := dtokit.Map[[]EntDTO](ctx, ents) if err != nil { panic(err) } _ = res // []EntDTO{V: "42", N: 12} } type Ent struct { V int N int } type EntDTO struct { V string `json:"v"` N int `json:"n"` } type EntMapping struct{} func (EntMapping) ToDTO(ctx context.Context, ent Ent) (EntDTO, error) { return EntDTO{V: strconv.Itoa(ent.V), N: ent.N}, nil } func (EntMapping) ToEnt(ctx context.Context, dto EntDTO) (Ent, error) { v, err := strconv.Atoi(dto.V) if err != nil { return Ent{}, err } return Ent{V: v, N: dto.N}, nil }
func Register ¶
func Register[From, To any](mapTo mapFunc[From, To], mapFrom mapFunc[To, From]) func()
Register function facilitates the registration of a mapping between two types. Optionally, if you don't intend to support bidirectional mapping, you can pass nil for the mapFrom argument. It's important to consider that supporting bidirectional mapping between an entity type and a DTO type often leads to the creation of non-partial DTO structures, enhancing their usability on the client side.
Example ¶
package main import ( "context" "encoding/json" "strconv" "go.llib.dev/frameless/pkg/dtokit" ) func main() { // JSONMapping will contain mapping from entities to JSON DTO structures. // registering Ent <---> EntDTO mapping _ = dtokit.Register[Ent, EntDTO]( EntMapping{}.ToDTO, EntMapping{}.ToEnt, ) // registering NestedEnt <---> NestedEntDTO mapping, which includes the mapping of the nested entities _ = dtokit.Register[NestedEnt, NestedEntDTO]( NestedEntMapping{}.ToDTO, NestedEntMapping{}.ToEnt, ) var v = NestedEnt{ ID: "42", Ent: Ent{ V: 42, }, } ctx := context.Background() dto, err := dtokit.Map[NestedEntDTO](ctx, v) if err != nil { // handle err return } _ = dto // data mapped into a DTO and now ready for marshalling /* NestedEntDTO{ ID: "42", Ent: EntDTO{ V: "42", }, } */ data, err := json.Marshal(dto) if err != nil { // handle error return } _ = data /* { "id": "42", "ent": { "v": "42" } } */ } type Ent struct { V int N int } type EntDTO struct { V string `json:"v"` N int `json:"n"` } type EntMapping struct{} func (EntMapping) ToDTO(ctx context.Context, ent Ent) (EntDTO, error) { return EntDTO{V: strconv.Itoa(ent.V), N: ent.N}, nil } func (EntMapping) ToEnt(ctx context.Context, dto EntDTO) (Ent, error) { v, err := strconv.Atoi(dto.V) if err != nil { return Ent{}, err } return Ent{V: v, N: dto.N}, nil } type NestedEnt struct { ID string Ent Ent } type NestedEntDTO struct { ID string `json:"id"` Ent EntDTO `json:"ent"` } type NestedEntMapping struct{} func (NestedEntMapping) ToEnt(ctx context.Context, dto NestedEntDTO) (NestedEnt, error) { return NestedEnt{ ID: dto.ID, Ent: dtokit.MustMap[Ent](ctx, dto.Ent), }, nil } func (NestedEntMapping) ToDTO(ctx context.Context, ent NestedEnt) (NestedEntDTO, error) { return NestedEntDTO{ ID: ent.ID, Ent: dtokit.MustMap[EntDTO](ctx, ent.Ent), }, nil }
Example (PartialDTOMappingSupport) ¶
package main import ( "context" "go.llib.dev/frameless/pkg/dtokit" ) func main() { // When we only need an Entity to EntityPartialDTO mapping. dtokit.Register[Ent, EntPartialDTO](EntToEntPartialDTO, nil)() var ( ctx = context.Background() v = Ent{V: 42, N: 12} ) partialDTO, err := dtokit.Map[EntPartialDTO](ctx, v) _, _ = partialDTO, err } type Ent struct { V int N int } type EntPartialDTO struct { N int `json:"n"` } func EntToEntPartialDTO(ctx context.Context, ent Ent) (EntPartialDTO, error) { return EntPartialDTO{N: ent.N}, nil }
Types ¶
type ErrMustMap ¶
type ErrMustMap struct{ Err error }
func (ErrMustMap) Error ¶
func (err ErrMustMap) Error() string
type Mapper ¶ added in v0.230.0
type Mapper[ENT any] interface { // NewiDTO should return back a new(DTO) value. // It is ideal to use with Unmarshal functions such as json.Unmarshal. // // The main reason for hiding the information of DTO type, // is because where you use a Mapper[Entity] interface // is often not aware what will be the DTO type, // especially with reusable generic code, // and most serializer implementation fine with accepting an "any" argument type. NewiDTO() (dtoPtr any) // MapFromiDTOPtr expected to map a *DTO value to an Entity value. // We use a DTO pointer here, because the user of Mapper doesn't know the type as well, // it just use the result of NewiDTO as an argument to Unmarshal. // // dtoPtr := m.NewiDTO() // _ = json.Unmarshal(data, dtoPtr) // ent, err := m.MapFromiDTOPtr(ctx, dtoPtr) // MapFromiDTOPtr(ctx context.Context, dtoPtr any) (ENT, error) // MapToiDTO expected to map an ENT value to a DTO value. // The result of this often passed to a Marshal function. // // dto, _ := m.MapToiDTO(ctx, ent) // data, _ := json.Marshal(dto) // MapToiDTO(context.Context, ENT) (DTO any, _ error) }
Mapper is a generic interface used for representing a Entity-DTO mapping relationship where the user of the Mapper is not aware of the concrete type of the DTO. This could be a case for when the user of the mapper simply uses the dto to pass to a marshaling/unmarshaling function.
Implemented by Mapping[Entity, DTO]
type MapperTo ¶ added in v0.240.0
type MapperTo[ENT, DTO any] interface { MapToDTO(context.Context, ENT) (DTO, error) MapToENT(context.Context, DTO) (ENT, error) }
MapperTo[ENT, DTO] represents a mapping between ENT and DTO. It is a generic way to express a mapping relationship when the user of the mapping is aware of the concrete DTO type.
Implemented by Mapping[Entity, DTO]
type Mapping ¶ added in v0.230.0
type Mapping[ENT, DTO any] struct { // ToENT is an optional function to describe how to map a DTO into an Entity. // // default: dtokit.Map[Entity, DTO](...) ToENT func(ctx context.Context, dto DTO) (ENT, error) // ToDTO is an optional function to describe how to map an Entity into a DTO. // // default: dtokit.Map[DTO, Entity](...) ToDTO func(ctx context.Context, ent ENT) (DTO, error) }
Mapping is a type safe implementation to represent a Mapping between an ENT and its DTO type. Mapping[ENT, DTO] implements Mapper[ENT].