Skip to content

[Feature] Add the ability for mold.FieldLevel to modify the values of other fields. #50

@ilxqx

Description

@ilxqx

I need a feature that can automatically translate data-dictionary fields in a Struct. Fortunately, I discovered the mold library—its reusability and generality are fascinating, and I’m truly grateful to everyone who has contributed!

However, for my specific requirement it’s still a bit short. I don’t want to touch the field itself that is tagged with trans (although in most cases that’s exactly what people do); instead, I want to modify another field that is strongly associated with it. In my scenario this associated field is, by convention, named “FieldName+Name” (it could also be determined by a tag parameter, but that’s another topic). The main problem right now is that I can’t obtain the reflect.Value of other fields in the struct through mold.FieldLevel.

The code below demonstrates my need, but it doesn’t compile yet:

package main

import (
	"context"
	"fmt"

	"github.com/go-playground/mold/v4"
	"github.com/samber/lo"
)

func main() {
	trans := mold.New()
	trans.SetTagName("trans")
	trans.Register("dict", func(_ context.Context, fl mold.FieldLevel) error {
		if fl.Param() == "user.status" {
			// I can't do this because it would directly overwrite the original value.
			// fl.Field().SetString(
			// 	lo.Ternary(fl.Field().String() == "E", "Enabled", "Disabled"),
			// )

			// I need to save the translated value in another field instead of directly overwriting the original value.
			// This code is just ideal pseudocode; I need something with similar functionality.
			fl.StructField("StatusName").SetString(
				lo.Ternary(fl.Field().String() == "E", "Enabled", "Disabled"),
			)
		}

		return nil
	})

	type Person struct {
		Name       string
		Status     string `trans:"dict=user.status"`
		StatusName string
	}

	person := Person{
		Name:   "John",
		Status: "E",
	}

	if err := trans.Struct(context.Background(), &person); err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", person)
}

I wonder if it's possible to provide a StructLevel parameter via mold.Func or offer a method through FieldLevel that can access the StructLevel instance it belongs to.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions