Skip to content

Issue with using default tag with pointer type #47

@hnimtadd

Description

@hnimtadd

TL;DR: When using the mod:"default" tag with a field of type *string, if the field is nil, the library assigns it to a pointer referencing an empty string ("") instead of the defined default value.


Context:

Hi team, thank you for the great work on this library!

While integrating it into my project, I encountered an unexpected behavior and am seeking your advice.

Here’s a simplified example to illustrate the issue:

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/go-playground/mold/v4/modifiers"
)

var conform = modifiers.New()

type User struct {
	Name *string `mod:"default=abc"`
}

func main() {
	user := User{}
	fmt.Println("Name:", user.Name) // Output: nil (as expected)

	err := conform.Struct(context.Background(), &user)
	if err != nil {
		log.Panic(err)
	}

	fmt.Println("Conformed Name:", *user.Name) // Output: "" (unexpected, expected "abc")
}

Problem:

The Name field in the User struct is of type *string and is configured with the mod:"default=abc" tag.

However, if the field is initially nil, the library assigns it to a pointer referencing an empty string ("") instead of a pointer referencing the expected default value ("abc").


Expected Behavior:

If the Name field is nil, it should be assigned to a pointer referencing the default value ("abc") as defined by the mod:"default=abc" tag


Investigation and proposal:

I traced the issue to the following section of code in the modifiers/multi.go file:

	case reflect.Ptr:
		fl.Field().Set(reflect.New(fl.Field().Type().Elem()))
	}

This code initializes a pointer field to point to an empty value (e.g., an empty string).

However, it does not account for the configured default value defined in the mod:"default=..." tag. As a result, the pointer field ends up pointing to an empty string instead of the specified default value.


To fix this, I suggest updating the logic to use the configured default value when initializing the pointer. Here’s a proposed modification:

case reflect.Ptr:
	value := fl.Param() // Retrieve the configured default value
	fl.Field().Set(reflect.ValueOf(&value)) // Set the field to point to the default value
}

Please let me know if this behavior is intentional or if there is a recommended way to achieve the expected behavior. Thanks in advance!

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