Categorygithub.com/go-playground/mold/v3
modulepackage
3.1.1
Repository: https://github.com/go-playground/mold.git
Documentation: pkg.go.dev

# README

Package mold

Project status Build Status Coverage Status Go Report Card GoDoc License

Package mold is a general library to help modify or set data within data structures and other objects.

How can this help me you ask, please see the examples here

Installation

Use go get.

go get -u github.com/go-playground/mold/v3

Then import the form package into your own code.

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

Simple example

package main

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

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

var tform *mold.Transformer

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

	type Test struct {
		String string `mold:"set"`
	}

	var tt Test

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

	var myString string
	err = tform.Field(context.Background(), &myString, "set")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(myString)
}

func transformMyData(ctx context.Context, t *mold.Transformer, value reflect.Value, param string) error {
	value.SetString("test")
	return nil
}

Full example

package main

import (
	"context"
	"fmt"
	"log"
	"net/url"

	"github.com/go-playground/form"

	"github.com/go-playground/mold/v3/modifiers"
	"github.com/go-playground/mold/v3/scrubbers"

	"gopkg.in/go-playground/validator.v9"
)

// This example is centered around a form post, but doesn't have to be
// just trying to give a well rounded real life example.

// <form method="POST">
//   <input type="text" name="Name" value="joeybloggs"/>
//   <input type="text" name="Age" value="3"/>
//   <input type="text" name="Gender" value="Male"/>
//   <input type="text" name="Address[0].Name" value="26 Here Blvd."/>
//   <input type="text" name="Address[0].Phone" value="9(999)999-9999"/>
//   <input type="text" name="Address[1].Name" value="26 There Blvd."/>
//   <input type="text" name="Address[1].Phone" value="1(111)111-1111"/>
//   <input type="text" name="active" value="true"/>
//   <input type="submit"/>
// </form>

var (
	conform  = modifiers.New()
	scrub    = scrubbers.New()
	validate = validator.New()
	decoder  = form.NewDecoder()
)

// Address contains address information
type Address struct {
	Name  string `mod:"trim" validate:"required"`
	Phone string `mod:"trim" validate:"required"`
}

// User contains user information
type User struct {
	Name    string    `mod:"trim"      validate:"required"              scrub:"name"`
	Age     uint8     `                validate:"required,gt=0,lt=130"`
	Gender  string    `                validate:"required"`
	Email   string    `mod:"trim"      validate:"required,email"        scrub:"emails"`
	Address []Address `                validate:"required,dive"`
	Active  bool      `form:"active"`
}

func main() {
	// this simulates the results of http.Request's ParseForm() function
	values := parseForm()

	var user User

	// must pass a pointer
	err := decoder.Decode(&user, values)
	if err != nil {
		log.Panic(err)
	}
	fmt.Printf("Decoded:%+v\n\n", user)

	// great not lets conform our values, after all a human input the data
	// nobody's perfect
	err = conform.Struct(context.Background(), &user)
	if err != nil {
		log.Panic(err)
	}
	fmt.Printf("Conformed:%+v\n\n", user)

	// that's better all those extra spaces are gone
	// let's validate the data
	err = validate.Struct(user)
	if err != nil {
		log.Panic(err)
	}

	// ok now we know our data is good, let's do something with it like:
	// save to database
	// process request
	// etc....

	// ok now I'm done working with my data
	// let's log or store it somewhere
	// oh wait a minute, we have some sensitive PII data
	// let's make sure that's de-identified first
	err = scrub.Struct(context.Background(), &user)
	if err != nil {
		log.Panic(err)
	}
	fmt.Printf("Scrubbed:%+v\n\n", user)
}

// this simulates the results of http.Request's ParseForm() function
func parseForm() url.Values {
	return url.Values{
		"Name":             []string{"  joeybloggs  "},
		"Age":              []string{"3"},
		"Gender":           []string{"Male"},
		"Email":            []string{"[email protected]  "},
		"Address[0].Name":  []string{"26 Here Blvd."},
		"Address[0].Phone": []string{"9(999)999-9999"},
		"Address[1].Name":  []string{"26 There Blvd."},
		"Address[1].Phone": []string{"1(111)111-1111"},
		"active":           []string{"true"},
	}
}

Special Information

  • To use a comma(,) within your params replace use it's hex representation instead '0x2C' which will be replaced while caching.

Contributing

I am definitly interested in the communities help in adding more scrubbers and modifiers. Please send a PR with tests, and prefereably no extra dependencies, at lease until a solid base has been built.

Complimentary Software

Here is a list of software that compliments using this library post decoding.

  • validator - Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving.
  • form - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.

License

Distributed under MIT License, please see license file in code for more details.

# Packages

No description provided by the author
No description provided by the author

# Functions

HasValue determines if a reflect.Value is it's default value.
New creates a new Transform object with default tag name of 'mold'.

# Variables

ErrInvalidDive describes an invalid dive tag configuration.
ErrInvalidKeysTag describes a misuse of the keys tag.
ErrUndefinedKeysTag describes an undefined keys tag when and endkeys tag defined.

# Structs

ErrInvalidTag defines a bad value for a tag being used.
ErrInvalidTransformation describes an invalid argument passed to `Struct` or `Field`.
An ErrInvalidTransformValue describes an invalid argument passed to Struct or Var.
ErrUndefinedTag defines a tag that does not exist.
Transformer is the base controlling object which contains all necessary information.

# Type aliases

Func defines a transform function for use.
StructLevelFunc accepts all values needed for struct level validation.