km

command module
v0.0.0-...-a21a979 Latest Latest
Warning

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

Go to latest
Published: May 11, 2024 License: BSD-3-Clause Imports: 17 Imported by: 0

README

Go Reference KM

KM

Art generated by copilot DALL-E 3

KM (Kanna Mapper) helps you auto-generate mapping between types and supports configuration using a TOML configuration file.

⚠️ It's still in early development so do not use it in production, also I am planning on a better usage experience so expect breaking changes.

Why KM?

Unlike other mappers, KM leverages code generation and does not use reflection, which means there are no errors during runtime, and offers much better performance than other solutions that use reflection.

✔️ Doesn't use reflection

✔️ Leverage fails early so nothing will generate in case of errors

✔️ Configurable

✔️ Different generation styles

✔️ Concurrent generation

Install

go install github.com/khatibomar/km@latest

Flags

Flags:
  -config string
        mapping configuration file (default "km.toml")
  -debug
        log result instead of writing to files
  -routines int
        number of routines (default 1)

Usage

First, create km.toml file, this file will hold the mapping configuration, and it's considered the root directory of the generator, which means if we have folder folder/sub_folder/km.toml the sub_folder is the root directory for mapper and you can't map things in folder

[settings]
style="value"
module="github.com/khatibomar/km/"
path_from_module="testdata"

[[mappings]]
  [mappings.source]
  name = "Car"
  path = "./car/car.go"

  [mappings.destination]
  name = "CarDTO"
  path = "./dto/car_dto.go"
  ignore = ["Owner"]

  [mappings.destination.map]
  FactoryModel = "Model"

[[mappings]]
  [mappings.source]
  name = "User"
  path = "./user/user.go"

  [mappings.destination]
  name = "UserDTO"
  path = "./dto/user_dto.go"

we are going to use testdata folder

So in settings we set PathFromModule to testdata this setting is nothing but how we can access the config file starting from the root of the project itself, not the config.

This is the tree of the testdata before running generation

  94 B    ┌─ car.go
  94 B ┌─ car
 163 B │  ┌─ user.go
 163 B ├─ user
 103 B │  ┌─ car_dto.go
 157 B │  ├─ user_dto.go
 260 B ├─ dto
 483 B ├─ km.toml
1000 B testdata

after that run km which will generate km_gen.go in the destination path.

tree after generation

  94 B    ┌─ car.go
  94 B ┌─ car
 163 B │  ┌─ user.go
 163 B ├─ user
 483 B ├─ km.toml
 103 B │  ┌─ car_dto.go
 157 B │  ├─ user_dto.go
 363 B │  ├─ km_gen.go
 623 B ├─ dto
1363 B testdata

we can see that km_gen.go is generated in the destination path.

package dto

import (
	"github.com/khatibomar/km/testdata/car"
	"github.com/khatibomar/km/testdata/user"
)

func (dest CarDTO) FromCar(src car.Car) CarDTO {
	dest.FactoryModel = src.Model
	dest.Color = src.Color
	dest.Speed = src.Speed
	return dest
}

func (dest UserDTO) FromUser(src user.User) UserDTO {
	dest.Name = src.Name
	dest.Age = src.Age
  	dest.MetaData = src.MetaData
	return dest
}

Settings

Global
setting Description
style specify mapping style, default style is value
module is the module of the repository
path_from_module how we can access the config file starting from the root of the project itself
Source
setting Description
name name of the type
path where can locate the type, root starts from config file
Destination
setting Description
name name of the type
path where can locate the type, root starts from config file
ignore fields to ignore during mapping
map map from destination to source field

Styles

Approach Description Use Case
pointer Modifies the existing instance of the destination directly. When you want to modify the existing instance of destination without creating a new one.
value Creates a copy of the destination struct, modifies the copy, and returns it, leaving the original intact. When you want to keep the original destination struct intact and produce a modified copy.
standalone A standalone function that takes destination as a parameter and returns a modified version of it. When you want to keep the modification logic separate from the struct's methods or need more flexibility in how you apply the modification.
Value
func (dest CarDTO) FromCar(src car.Car) CarDTO {
	dest.FactoryModel = src.Model
	dest.Color = src.Color
	dest.Speed = src.Speed
	return dest
}
pointer
func (dest *CarDTO) FromCar(src car.Car) {
	dest.FactoryModel = src.Model
	dest.Color = src.Color
	dest.Speed = src.Speed
}
standalone
func CarDTOFromCar(dest CarDTO, src car.Car) CarDTO {
	dest.FactoryModel = src.Model
	dest.Color = src.Color
	dest.Speed = src.Speed
	return dest
}

Upcoming

  • Refactor code
  • Adding more tests
  • Support for map <-> struct
  • Better documentation
  • Handle conversion between types
  • Recursive mapping for complex fields

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

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