package arg
import (
"encoding"
"fmt"
"reflect"
"unicode"
"unicode/utf8"
scalar "github.com/alexflint/go-scalar"
)
var textUnmarshalerType = reflect .TypeOf ([]encoding .TextUnmarshaler {}).Elem ()
type cardinality int
const (
zero cardinality = iota
one
multiple
unsupported
)
func (k cardinality ) String () string {
switch k {
case zero :
return "zero"
case one :
return "one"
case multiple :
return "multiple"
case unsupported :
return "unsupported"
default :
return fmt .Sprintf ("unknown(%d)" , int (k ))
}
}
func cardinalityOf(t reflect .Type ) (cardinality , error ) {
if scalar .CanParse (t ) {
if isBoolean (t ) {
return zero , nil
}
return one , nil
}
if t .Kind () == reflect .Ptr {
t = t .Elem ()
}
switch t .Kind () {
case reflect .Slice :
if !scalar .CanParse (t .Elem ()) {
return unsupported , fmt .Errorf ("cannot parse into %v because %v not supported" , t , t .Elem ())
}
return multiple , nil
case reflect .Map :
if !scalar .CanParse (t .Key ()) {
return unsupported , fmt .Errorf ("cannot parse into %v because key type %v not supported" , t , t .Elem ())
}
if !scalar .CanParse (t .Elem ()) {
return unsupported , fmt .Errorf ("cannot parse into %v because value type %v not supported" , t , t .Elem ())
}
return multiple , nil
default :
return unsupported , fmt .Errorf ("cannot parse into %v" , t )
}
}
func isBoolean(t reflect .Type ) bool {
switch {
case isTextUnmarshaler (t ):
return false
case t .Kind () == reflect .Bool :
return true
case t .Kind () == reflect .Ptr && t .Elem ().Kind () == reflect .Bool :
return true
default :
return false
}
}
func isTextUnmarshaler(t reflect .Type ) bool {
return t .Implements (textUnmarshalerType ) || reflect .PtrTo (t ).Implements (textUnmarshalerType )
}
func isExported(field string ) bool {
r , _ := utf8 .DecodeRuneInString (field )
return unicode .IsLetter (r ) && unicode .IsUpper (r )
}
func isZero(v reflect .Value ) bool {
t := v .Type ()
if t .Kind () == reflect .Ptr || t .Kind () == reflect .Slice || t .Kind () == reflect .Map || t .Kind () == reflect .Chan || t .Kind () == reflect .Interface {
return v .IsNil ()
}
if !t .Comparable () {
return false
}
return v .Interface () == reflect .Zero (t ).Interface ()
}
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 .