package uritemplate
import "strings"
type Values map [string ]Value
func (v Values ) Set (name string , value Value ) {
v [name ] = value
}
func (v Values ) Get (name string ) Value {
if v == nil {
return Value {}
}
return v [name ]
}
type ValueType uint8
const (
ValueTypeString = iota
ValueTypeList
ValueTypeKV
valueTypeLast
)
var valueTypeNames = []string {
"String" ,
"List" ,
"KV" ,
}
func (vt ValueType ) String () string {
if vt < valueTypeLast {
return valueTypeNames [vt ]
}
return ""
}
type Value struct {
T ValueType
V []string
}
func (v Value ) String () string {
if v .Valid () && v .T == ValueTypeString {
return v .V [0 ]
}
return ""
}
func (v Value ) List () []string {
if v .Valid () && v .T == ValueTypeList {
return v .V
}
return nil
}
func (v Value ) KV () []string {
if v .Valid () && v .T == ValueTypeKV {
return v .V
}
return nil
}
func (v Value ) Valid () bool {
switch v .T {
default :
return false
case ValueTypeString :
return len (v .V ) > 0
case ValueTypeList :
return len (v .V ) > 0
case ValueTypeKV :
return len (v .V ) > 0 && len (v .V )%2 == 0
}
}
func (v Value ) expand (w *strings .Builder , spec varspec , exp *expression ) error {
switch v .T {
case ValueTypeString :
val := v .V [0 ]
var maxlen int
if max := len (val ); spec .maxlen < 1 || spec .maxlen > max {
maxlen = max
} else {
maxlen = spec .maxlen
}
if exp .named {
w .WriteString (spec .name )
if val == "" {
w .WriteString (exp .ifemp )
return nil
}
w .WriteByte ('=' )
}
return exp .escape (w , val [:maxlen ])
case ValueTypeList :
var sep string
if spec .explode {
sep = exp .sep
} else {
sep = ","
}
var pre string
var preifemp string
if spec .explode && exp .named {
pre = spec .name + "="
preifemp = spec .name + exp .ifemp
}
if !spec .explode && exp .named {
w .WriteString (spec .name )
w .WriteByte ('=' )
}
for i := range v .V {
val := v .V [i ]
if i > 0 {
w .WriteString (sep )
}
if val == "" {
w .WriteString (preifemp )
continue
}
w .WriteString (pre )
if err := exp .escape (w , val ); err != nil {
return err
}
}
case ValueTypeKV :
var sep string
var kvsep string
if spec .explode {
sep = exp .sep
kvsep = "="
} else {
sep = ","
kvsep = ","
}
var ifemp string
var kescape escapeFunc
if spec .explode && exp .named {
ifemp = exp .ifemp
kescape = escapeLiteral
} else {
ifemp = ","
kescape = exp .escape
}
if !spec .explode && exp .named {
w .WriteString (spec .name )
w .WriteByte ('=' )
}
for i := 0 ; i < len (v .V ); i += 2 {
if i > 0 {
w .WriteString (sep )
}
if err := kescape (w , v .V [i ]); err != nil {
return err
}
if v .V [i +1 ] == "" {
w .WriteString (ifemp )
continue
}
w .WriteString (kvsep )
if err := exp .escape (w , v .V [i +1 ]); err != nil {
return err
}
}
}
return nil
}
func String (v string ) Value {
return Value {
T : ValueTypeString ,
V : []string {v },
}
}
func List (v ...string ) Value {
return Value {
T : ValueTypeList ,
V : v ,
}
}
func KV (kv ...string ) Value {
if len (kv )%2 != 0 {
panic ("uritemplate.go: count of the kv must be even number" )
}
return Value {
T : ValueTypeKV ,
V : kv ,
}
}
The pages are generated with Golds v0.8.4 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .