package arg
import (
"fmt"
"reflect"
"strings"
scalar "github.com/alexflint/go-scalar"
)
func setSliceOrMap(dest reflect .Value , values []string , clear bool ) error {
if !dest .CanSet () {
return fmt .Errorf ("field is not writable" )
}
t := dest .Type ()
if t .Kind () == reflect .Ptr {
dest = dest .Elem ()
t = t .Elem ()
}
switch t .Kind () {
case reflect .Slice :
return setSlice (dest , values , clear )
case reflect .Map :
return setMap (dest , values , clear )
default :
return fmt .Errorf ("setSliceOrMap cannot insert values into a %v" , t )
}
}
func setSlice(dest reflect .Value , values []string , clear bool ) error {
var ptr bool
elem := dest .Type ().Elem ()
if elem .Kind () == reflect .Ptr && !elem .Implements (textUnmarshalerType ) {
ptr = true
elem = elem .Elem ()
}
if clear && !dest .IsNil () {
dest .SetLen (0 )
}
for _ , s := range values {
v := reflect .New (elem )
if err := scalar .ParseValue (v .Elem (), s ); err != nil {
return err
}
if !ptr {
v = v .Elem ()
}
dest .Set (reflect .Append (dest , v ))
}
return nil
}
func setMap(dest reflect .Value , values []string , clear bool ) error {
var keyIsPtr bool
keyType := dest .Type ().Key ()
if keyType .Kind () == reflect .Ptr && !keyType .Implements (textUnmarshalerType ) {
keyIsPtr = true
keyType = keyType .Elem ()
}
var valIsPtr bool
valType := dest .Type ().Elem ()
if valType .Kind () == reflect .Ptr && !valType .Implements (textUnmarshalerType ) {
valIsPtr = true
valType = valType .Elem ()
}
if clear && !dest .IsNil () {
for _ , k := range dest .MapKeys () {
dest .SetMapIndex (k , reflect .Value {})
}
}
if dest .IsNil () {
dest .Set (reflect .MakeMap (dest .Type ()))
}
for _ , s := range values {
pos := strings .Index (s , "=" )
if pos == -1 {
return fmt .Errorf ("cannot parse %q into a map, expected format key=value" , s )
}
k := reflect .New (keyType )
if err := scalar .ParseValue (k .Elem (), s [:pos ]); err != nil {
return err
}
if !keyIsPtr {
k = k .Elem ()
}
v := reflect .New (valType )
if err := scalar .ParseValue (v .Elem (), s [pos +1 :]); err != nil {
return err
}
if !valIsPtr {
v = v .Elem ()
}
dest .SetMapIndex (k , v )
}
return nil
}
The pages are generated with Golds v0.8.2 . (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 .