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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to provide default values to converters? #93

Closed
1 of 3 tasks
lampajr opened this issue Nov 2, 2023 · 3 comments · Fixed by #96
Closed
1 of 3 tasks

Is it possible to provide default values to converters? #93

lampajr opened this issue Nov 2, 2023 · 3 comments · Fixed by #96
Labels
feature New feature or request

Comments

@lampajr
Copy link
Contributor

lampajr commented Nov 2, 2023

Hi everyone 👋,

First of all I am a new user of this tool and this is pretty amazing!!

Have you read the project readme?

  • Yes, but it does not include related information regarding my question.
  • Yes, but the steps described do not work.
  • Yes, but I am having difficulty understanding it and want clarification.

Describe your question
I apologize if I am asking for something stupid or simple but I am struggling finding how I can provide some defaults to be applied during the mapping, here a possible use case:

package example

// goverter:converter
type Converter interface {
    // goverter:autoMap Address
    Convert(Person) FlatPerson
}

type Person struct {
    Name    string
    Age     int
    Address Address
}
type Address struct {
    Street  string
    ZipCode string
}
type FlatPerson struct {
    Name    string
    Age     int
    Street  string
    ZipCode string
}

Use case:

Let's assume that we have a default for Name whenever the source, in this case Person object, does not provide it.

Q1: Is there a way to accomplish this goal without having to create a custom function converter?

// goverter:converter
type Converter interface {
    // goverter:autoMap Address
    // goverter:map Name Name <DEFAULT>
    Convert(Person) FlatPerson
}

Q2: In my specific case I do have an autogenerated constructor that automatically sets all defaults for a specific struct, is there a way to provide that custom constructor to goverter such that the autogenerated code initialize the struct using that constructor instead of simple FlatPerson{} initialization?

// goverter:converter
type Converter interface {
    // goverter:autoMap Address
    // goverter:init <MY-FLATPERSON_CONSTRUCTOR>
    Convert(Person) FlatPerson
}
@lampajr lampajr added the question Further information is requested label Nov 2, 2023
@jmattheis
Copy link
Owner

Q1: Is there a way to accomplish this goal without having to create a custom function converter?

You can use a method mapping like so

// goverter:converter
type Converter interface {
	// goverter:map Age | DefaultAge
	Convert(Input) Output
}

type Input struct {
	Name string
}
type Output struct {
	Name string
	Age  int
}

func DefaultAge() int {
	return 42
}

Q2: In my specific case I do have an autogenerated constructor that automatically sets all defaults for a specific struct, is there a way to provide that custom constructor to goverter such that the autogenerated code initialize the struct using that constructor instead of simple FlatPerson{} initialization?

This is currently not possible but sounds like a useful addition. I'll keep this as a feature request.

@jmattheis jmattheis added feature New feature or request and removed question Further information is requested labels Nov 2, 2023
@lampajr
Copy link
Contributor Author

lampajr commented Nov 2, 2023

Many thanks for the prompt answer!

You can use a method mapping like so

// goverter:converter
type Converter interface {
	// goverter:map Age | DefaultAge
	Convert(Input) Output
}

type Input struct {
	Name string
}
type Output struct {
	Name string
	Age  int
}

func DefaultAge() int {
	return 42
}

Yeah exactly, but in that case I think it will be set to 42 even if provided in the Input obj right? I mean I was curious if there was a way to set a default mapping only if the source object does not have it or if it is nil.

This is currently not possible but sounds like a useful addition. I'll keep this as a feature request.

I would be happy to contribute, or at least to try contributing, if that sounds good for you!

@jmattheis
Copy link
Owner

Yeah exactly, but in that case I think it will be set to 42 even if provided in the Input obj right?

Correct.

if there was a way to set a default mapping only if the source object does not have it

You could do it like this, but there is no way around the function definition

// goverter:converter
type Converter interface {
	// goverter:map Age | DefaultAge
	Convert(Input) Output
}

type Input struct {
	Name string
	Age  *int
}
type Output struct {
	Name string
	Age  int
}

func DefaultAge(source *int) int {
	if source == nil {
		return 42
	}
	return *source
}

or if it is nil.

this isn't currently possible.

I would be happy to contribute, or at least to try contributing, if that sounds good for you!

Sure. I'm not sure yet about the config name yet, but we can decide this later and then rename it in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants