mardi 8 décembre 2020

How to change empty *strings to nil using mold package?

During validation of user input I wanna set to nil some empty *strings in some structs.

E.g. I have this struct:

type User {
  Username *string
}

If Username == "" I wanna set Username to nil before proceed.

But I wanna do this using tags, e.g.:

type User {
  Username *string `mod:"nil_if_empty`
}

because I'm already using this package: https://github.com/go-playground/mold in my project for sanitize.

So I'm creating a custom function to set empty strings to nil, but I'm stuck.

Reproduction: https://play.golang.org/p/_DlluqE2Y3k

package main

import (
    "context"
    "fmt"
    "log"
    "reflect"

    "github.com/go-playground/mold/v3"
)

var tform *mold.Transformer

func main() {
    tform = mold.New()
    tform.Register("nilEmptyString", nilEmptyString)

    type Test struct {
        String *string `mold:"nilEmptyString"`
    }

    myEmptyString := ""
    tt := Test{String: &myEmptyString}

    err := tform.Struct(context.Background(), &tt)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%+v\n", tt)
}

func nilEmptyString(_ context.Context, _ *mold.Transformer, v reflect.Value, _ string) error {
    s, ok := v.Interface().(*string)
    if !ok { // ok is always false, why?
        return nil
    }

    if s != nil && *s != "" {
        return nil
    }

    if s != nil && *s == "" {
        // v.SetPointer(nil) // should I use this?
    }

    // v.Set(nil) // how to do this?

    return nil
}
  1. Why ok in s, ok := v.Interface().(*string) is always false?

  2. How to set v to nil? Why is v.Set(nil) wrong?

I hope this is a good question to ask on StackOverflow. If not tell me how to improve.

Thanks.





Aucun commentaire:

Enregistrer un commentaire