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

documentation: convert and map option behavior #41

Open
iamKunal opened this issue Sep 3, 2023 · 3 comments
Open

documentation: convert and map option behavior #41

iamKunal opened this issue Sep 3, 2023 · 3 comments
Labels
documentation Improvements or additions to documentation

Comments

@iamKunal
Copy link

iamKunal commented Sep 3, 2023

I am able to use map for mapping a field within model to struct inside domain directly but doing the same via a convert does not work.

I also tried using a pointer to the field (as argument to the convert function) but it is still of no use.

On a side note, I am using this as an alternative to mapstruct in Java (https://mapstruct.org/)

Domains&Models

type SubA struct {
 SomeString1 string
 SomeInteger2 int64
}

type Domain struct {
 Sub *SubA
}


type Model {
 SomeString1 string
 SomeString2 string
}

YML

generated:
  setup: ./mapping.go
  output: ../gen/mapper.gen.go

Setup Go

type Copygen interface {
	// map Model.SomeString1 Domain.Sub.SomeString1
	Mapper(model *Model) *Domain
}


// convert Model.SomeString2 Domain.Sub.SomeInteger2
func StringToInt64(s string) int64 {
	v, err := strconv.Atoi(s)
	if err != nil {
		v = 1
	}
	return int64(v)
}

Output

Generation

package copygen

import (
	"strconv"
)

func StringToInt64(s string) int64 {
	v, err := strconv.Atoi(s)
	if err != nil {
		v = 1
	}
	return int64(v)
}

// Mapper copies a *Model to a *Domain.
func MapAvailableIndexToIndexCard(tS *Domain, fS *Model) {
	// *Domain fields
	tS.Sub.SomeString1 = fS.SomeString1
}

Environment

Operating System: MacOS
Copygen Version: v0.4.0

@iamKunal iamKunal added the edge case An error occurred. label Sep 3, 2023
@switchupcb
Copy link
Owner

I may need more information from you to consider this an edge case.

Context

Using the map or tag option disables the automatcher, which allows you to manually match fields. In order to re-enable the automatcher, use the automatch option. Options are evaluated in order of declaration, so using automatch .* after declaring map and tag options provides an easy way to re-enable the automatcher for remaining fields.
https://github.com/switchupcb/copygen#manual

Your example includes a single function Mapper to map a Model.SomeString1 to Domain.Sub.SomeString1. This configuration disables the automatcher, so the MapAvailableIndexToIndexCard function will only assign those fields as intended.

You have defined a conversion function StringToInt64 that converts a Model.SomeString2 to Domain.Sub.SomeInteger2. Therefore, there is no issue in the current output (given that your map function does not involve these fields).

To reiterate:

  1. Using map disables the automatcher, which prevents copygen from assigning fields other than Model.SomeString1 to Domain.Sub.SomeString1.
  2. A conversion function is defined, but is not used since Model.SomeString2 to Domain.Sub.SomeInteger2 is not matched during the Copy Function Generation.

Solution

I assume that you would like these two fields to be matched in addition to the mapped fields.

If this is the case, you must rewrite your setup file.

Example Setup File 1

type Copygen interface {
	// map Model.SomeString1 Domain.Sub.SomeString1
        // map Model.SomeString2 Domain.Sub.SomeInteger2
	Mapper(model *Model) *Domain
}

Example Setup File 2

type Copygen interface {
	// automatch .*
        // map Model.SomeString1 Domain.Sub.SomeString1
	Mapper(model *Model) *Domain
}

If either of these configurations do not work, please ask me to re-open this issue with further context.

@switchupcb switchupcb added documentation Improvements or additions to documentation and removed edge case An error occurred. labels Sep 18, 2023
@switchupcb
Copy link
Owner

switchupcb commented Sep 18, 2023

Upon further review of the Copygen README, this reopened issue is currently categorized as a user error (due to documentation).

Issue

This user error has occurred because the behavior of the conversion option as a modifying option — as opposed to a matching option — is not clear. A matching option (e.g. map, automatch, tag) determines whether the field will be matched to another field, but a modifying option (e.g. convert) is only apply when a field is matched.

Solution

This issue is fixed once a clarifying statement is added for matching vs. modifier option behavior (including the convert option), unless the user has identified a logical edge case in Copygen's behavior. It must be clear to the user that the convert option only works on fields that are matched.

@switchupcb switchupcb reopened this Sep 18, 2023
@switchupcb switchupcb changed the title Unable to use convert for conversion from single depth field to multi-depth field user error: convert and map option behavior Sep 18, 2023
@switchupcb switchupcb changed the title user error: convert and map option behavior documentation: convert and map option behavior Sep 19, 2023
@iamKunal
Copy link
Author

It must be clear to the user that the convert option only works on fields that are matched.

Ohhh. This feels like double work in many cases though.

I had to go ahead with goverter as it was saner in this as well as it raised an error in case any field was not matched.

I'd recommend adding a flag for error as well just in case.

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

No branches or pull requests

2 participants