uri

package module
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2022 License: MIT Imports: 13 Imported by: 34

README

GoDoc Build Status Go Report Card codecov

Support for go 1.12+

Older versions will probably work, but are not officially supported or tested against.

Known Issues:

  • maps will not work before 1.12 because of use of reflect.RangeMap

uri

A convenient and easy way to convert from a uri to a struct or vic-versa. wikipedia

special keywords

  • origin (scheme:host/path)
  • scheme
  • authority (userinfo@host)
    • userinfo
      • username
      • password
    • host (includes port)
    • port
  • fragment

struct tags

  • uri - the name of the variable or to designate a special keywords (schema, host, etc). empty defaults the exact name of the struct (same as json tags)
  • default - defined the default value of a variable
  • required - if the param is missing, unmarshal will return an error
  • format -
    • time.Time: time format field for marshaling of time.Time format:"2006-01-02T15:04:05Z"
    • rune/int32: format:"rune"

Other Options

Use "json" struct tag values

You may use existing "json" struct tag values instead of defining "uri" values for query parameter names. The uri tag can be used to override the values in the json struct tag.

Non-Standard Query Params Support

Arrays/Slices

Arrays are supported by passing a comma separated list or by passing the value multiple times

  • ?array=1,2,3,4,5,6
  • ?array=1&array=2&array=3&array=4
Maps

Maps are supported by providing the key value param into the value with a colon : in between them. Multiple pairs can be passed as separated params or joined with the pipe |

  • map[string]int ?map=a:1|b:2|c:3
  • map[int]string ?map=1:a&map=2:b&map=3:c
  • map[string][]int ?map=a:1,2,3|b:4,5,6
  • map[int]time.Time 'format:"2006-01-02' ?map=0:2020-01-01

example 1

If we have the uri "http://example.com/path/to/page?name=ferret&color=purple" we can unmarshal this to a predefined struct as follows:

type Example struct {
    Scheme string `uri:"scheme"`
    Host   string `uri:"Host"`
    Path   string `uri:"path"`
    Name   string `uri:"name"`
    Color  string `uri:"color"`
}

func() {
e := Example{}

err := uri.Unmarshal("http://example.com/path/to/page?name=ferret&color=purple", &e)
}

This would become the following struct:

e := Example{
    Schema: "http",
    Host:   "example.com",
    Path:   "path/to/page",
    Name:   "ferret",
    Color:  "purple",
    }

example 2 - defaults

var site = "http://example.org/wiki/Main_Page?Option1=10"

type MyStruct struct {
    Path    string `uri:"path"`
    Option1 int
    Text    string `default:"qwerty"`
}

func Parse() {
    s := &MyStruct{}
    uri.Unmarshal(site, s)
}

this becomes

e := &MyStruct{
    Path: "/wiki/Main_Page"
    Option1: 10,
    Text: "qwerty",
}

example 3 - required field

type Example struct {
    Name string `uri:"name"`
    Token string `uri:"token" required:"true"`
}
func Parse() {
   site := "?name=hello"
   e := &Example{}
   err := uri.Unmarshal(site, e)
}

Result

    token is required

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetFieldString

func GetFieldString(value reflect.Value, sTag reflect.StructTag) string

GetFieldString returns a string representation of a Value booleans become true/false nil pointers return "nil" slices combine elements with a comma. []int{1,2,3} -> "1,2,3"

Example
name := "hello world"
s := GetFieldString(reflect.ValueOf(name), "")
fmt.Println(s)

var i *int
s = GetFieldString(reflect.ValueOf(i), "")
fmt.Println(s)

v := []int{2, 1, 3}
s = GetFieldString(reflect.ValueOf(v), "")
fmt.Println(s)
Output:

hello world
nil
2,1,3

func Marshal

func Marshal(v interface{}) (s string)

Marshal a struct into a string representation of a uri Note: Marshal panics if a struct or pointer to a struct is not provided

Example
v := struct {
	Scheme string `uri:"scheme"`
	Host   string `uri:"host"`
	Path   string `uri:"path"`
	Name   string `uri:"name"`
	Count  int    `uri:"num"`
}{
	Scheme: "https",
	Host:   "localhost",
	Path:   "root/index.html",
	Name:   "Hello World",
	Count:  11,
}
s := Marshal(v)
fmt.Println(s)
Output:

https://localhost/root/index.html?name=Hello+World&num=11

func MarshalUnescaped added in v0.4.0

func MarshalUnescaped(v interface{}) string

MarshalUnescaped is the same as marshal but without url encoding the values

func SetField

func SetField(value reflect.Value, s string, sField reflect.StructField) error

SetField converts the string s to the type of value and sets the value if possible. Pointers and slices are recursively dealt with by deferencing the pointer or creating a generic slice of type value. All structs and alias' that implement encoding.TextUnmarshaler are suppported

func Unmarshal

func Unmarshal(uri string, v interface{}) error

Unmarshal copies a standard parsable uri to a predefined struct [scheme:][//[userinfo@]host][/]path[?query][#fragment] scheme:opaque[?query][#fragment]

Example
v := struct {
	Scheme string `uri:"scheme"`
	Host   string `uri:"host"`
	Path   string `uri:"path"`
	Name   string `uri:"name"`
	Count  int    `uri:"num"`
}{}
s := "https://localhost/root/index.html?name=Hello+World&num=11"
Unmarshal(s, &v)
fmt.Printf("scheme:%s\nhost:%s\npath:%s\nname:%s\ncount:%d", v.Scheme, v.Host, v.Path, v.Name, v.Count)
Output:

scheme:https
host:localhost
path:/root/index.html
name:Hello World
count:11

Types

This section is empty.

Jump to

Keyboard shortcuts

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