sp

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2026 License: MIT Imports: 7 Imported by: 0

README

sp

Zero-dependencies package to encodes structs into url.Values.

Installation

go get github.com/ohzqq/sp

Usage

import (
    "github.com/ohzqq/sp"
)

qs Readme

refer to original

Package qs exports NewEncoder() function to create an encoder.

Encoder caches struct info to speed up encoding process, use a single instance is highly recommended.

Use WithTagAlias() func to register custom tag alias (default is qs)

encoder = qs.NewEncoder(
    qs.WithTagAlias("myTag"),
)

Encoder has Values() and Encode() functions to encode structs into url.Values.

Supported data types:
  • all basic types (bool, uint, string, float64,...)
  • struct
  • slice, array
  • pointer
  • time.Time
  • custom type
Example
type Query struct {
    Tags   []string  `qs:"tags"`
    Limit  int       `qs:"limit"`
    From   time.Time `qs:"from"`
    Active bool      `qs:"active,omitempty"`  //omit empty value
    Ignore float64   `qs:"-"`                 //ignore
}

query := &Query{
    Tags:   []string{"docker", "golang", "reactjs"},
    Limit:  24,
    From:   time.Unix(1580601600, 0).UTC(),
    Ignore: 0,
}

encoder := qs.NewEncoder()
values, err := encoder.Values(query)
if err != nil {
    // Handle error
}
fmt.Println(values.Encode()) //(unescaped) output: "from=2020-02-02T00:00:00Z&limit=24&tags=docker&tags=golang&tags=reactjs"
Bool format

Use int option to encode bool to integer

type Query struct {
    DefaultFmt bool `qs:"default_fmt"`
    IntFmt     bool `qs:"int_fmt,int"`
}

query := &Query{
    DefaultFmt: true, 
    IntFmt:     true,
}
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) // (unescaped) output: "default_fmt=true&int_fmt=1"
Time format

By default, package encodes time.Time values as RFC3339 format.

Including the "second" or "millis" option to signal that the field should be encoded as second or millisecond.

type Query struct {
    Default time.Time   `qs:"default_fmt"`
    Second  time.Time   `qs:"second_fmt,second"` //use `second` option
    Millis  time.Time   `qs:"millis_fmt,millis"` //use `millis` option
}

t := time.Unix(1580601600, 0).UTC()
query := &Query{
    Default: t,
    Second:  t,
    Millis:  t,
}

encoder := qs.NewEncoder()
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) // (unescaped) output: "default_fmt=2020-02-02T00:00:00Z&millis_fmt=1580601600000&second_fmt=1580601600"
Slice/Array Format

Slice and Array default to encoding into multiple URL values of the same value name.

type Query struct {
    Tags []string `qs:"tags"`
}

values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags=foo&tags=bar"

Including the comma option to signal that the field should be encoded as a single comma-delimited value.

type Query struct {
    Tags []string `qs:"tags,comma"`
}

values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags=foo,bar"

Including the bracket option to signal that the multiple URL values should have "[]" appended to the value name.

type Query struct {
    Tags []string `qs:"tags,bracket"`
}

values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags[]=foo&tags[]=bar"

The index option will append an index number with brackets to value name.

type Query struct {
    Tags []string `qs:"tags,index"`
}

values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) //(unescaped) output: "tags[0]=foo&tags[1]=bar"
Nested structs

All nested structs are encoded including the parent value name with brackets for scoping.

type User struct {
    Verified bool      `qs:"verified"`
    From     time.Time `qs:"from,millis"`
}

type Query struct {
    User User `qs:"user"`
}

query := Query{
    User: User{
        Verified: true,
        From: time.Now(),
    },
}
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) //(unescaped) output: "user[from]=1601623397728&user[verified]=true"
Custom Type

Implement funcs:

  • EncodeParam to encode itself into query param.
  • IsZero to check whether an object is zero to determine whether it should be omitted when encoding.
type NullableName struct {
	First string
	Last  string
}

func (n NullableName) EncodeParam() (string, error) {
	return n.First + n.Last, nil
}

func (n NullableName) IsZero() bool {
	return n.First == "" && n.Last == ""
}

type Struct struct {
    User  NullableName `qs:"user"`
    Admin NullableName `qs:"admin,omitempty"`
}

s := Struct{
    User: NullableName{
        First: "son",
        Last:  "huynh",
    },
}
encoder := qs.NewEncoder()

values, err := encoder.Values(&s)
if err != nil {
    // Handle error
    fmt.Println("failed")
    return
}
fmt.Println(values.Encode()) //(unescaped) output: "user=sonhuynh"
Limitation
  • if elements in slice/array are struct data type, multi-level nesting are limited
  • no decoder yet

Will improve in future versions

License

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BindQueryParams added in v0.0.2

func BindQueryParams[Q ~map[string][]string](v Q, target any) error

BindQueryParams binds query params to bindable object

func Decode

func Decode[Q ~map[string][]string](v Q, t any) error

Decode takes url.Values and decodes it to a struct. see https://pkg.go.dev/github.com/labstack/echo/v5 for documentation.

func Encode

func Encode[Q map[string][]string](v any) (Q, error)

Encode encodes a struct to url.Values. see https://pkg.go.dev/github.com/sonh/qs for documentation.

Types

type BindUnmarshaler

type BindUnmarshaler interface {
	// UnmarshalParam decodes and assigns a value from an form or query param.
	UnmarshalParam(param string) error
}

BindUnmarshaler is the interface used to wrap the UnmarshalParam method. Types that don't implement this, but do implement encoding.TextUnmarshaler will use that interface instead.

type DefaultBinder

type DefaultBinder struct{}

DefaultBinder is the default implementation of the Binder interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL