jmattheis / goverter

Generate type-safe Go converters by simply defining an interface
https://goverter.jmattheis.de/
MIT License
464 stars 43 forks source link

Mapping context values #68

Open jmattheis opened 1 year ago

jmattheis commented 1 year ago

Goverter should allow passing a mapping context through converter methods for custom conversions. This allows more customizability when the conversion requires other state. See also https://mapstruct.org/documentation/stable/api/org/mapstruct/Context.html

Example:

// goverter:converter
// goverter:extend LookupUser
type Converter interface {
    Convert(source Input, context UserContext) (Output, error)
}

type UserContext struct {
    UserNames map[int]string
}

func LookupUser(userID int, context UserContext) (User, error) {
    user := User{ID: userID}
    name, ok := context.UserNames[userID]
    if !ok {
        return user, fmt.Errorf("user with id %d not found", userID)
    }
    user.Name = name
    return user, nil
}

type Input struct {  UserIDs []int }
type Output struct { Users []User  }
type User struct {
    ID int
    Name string
}

Conversion contexts are additional parameters that are passed into the conversion methods (See Convert method from Converter), and they should be passed into custom methods (See LookupUser).

Please :+1: this issue if you like this functionality. If you have a specific use-case in mind, feel free to comment it.

pavelpatrin commented 1 year ago

@jmattheis can I hope that this feature will be implemented once upon a time?

jmattheis commented 1 year ago

@pavelpatrin Yes, but it doesn't have a high priority on my to-do list.

becash commented 1 week ago

Hi, a made a beta version for that , it add "arguments", is a custom structure, that can be used in internal functions, say me a opinion, maybe some improvements, for me is all what i need

https://github.com/becash/goverter jmattheis

jmattheis commented 1 week ago

Hey @becash, it seems like the beta version has hardcoded the domain.Arguments type with a fixed position in the conversion method calls. I find this solution to inflexible, with the features https://github.com/jmattheis/goverter/issues/143 and https://github.com/jmattheis/goverter/issues/147 goverter needs a way to define arguments in a certain usage like source, target, and context.

If any of these tickets are implemented they should built the foundation to support this otherwise it probably has to be rewritten afterwards.

becash commented 3 days ago

of course is a beta, @jmattheis, i see problems that you mention, what you thing as idea? can be improved, or maybe replaced ?

about type name , is need to put in config? also need to indicate import path, maybe can you recomend a beter way also about "switch sig.Params().Len()" ... that im modify, i`m also thing it can me make better,
if you thing that my ideea can live, i can improve, to add in repository, but if you not agree, for me it work normal

jmattheis commented 1 day ago

Types that are context should be inferred from the conversion method signature.

// goverter:converter
type Converter interface {
    // goverter:arg:context ctxDB
    // goverter:arg:context ctxUsers
    // goverter:arg:source myInput
    Convert(ctxDB Database, myInput []Input, ctxUsers UserContext) []Output
}

Internally we can mark the Converter interface is context by default, to keep backwards compatibility.