// Package scalar parses strings into values of scalar type.

package scalar

import (
	
	
	
	
	
	
	
	
	
)

// The reflected form of some special types
var (
	textUnmarshalerType = reflect.TypeOf([]encoding.TextUnmarshaler{}).Elem()
	durationType        = reflect.TypeOf(time.Duration(0))
	mailAddressType     = reflect.TypeOf(mail.Address{})
	macType             = reflect.TypeOf(net.HardwareAddr{})
	urlType             = reflect.TypeOf(url.URL{})
)

var (
	errNotSettable    = errors.New("value is not settable")
	errPtrNotSettable = errors.New("value is a nil pointer and is not settable")
)

// Parse assigns a value to v by parsing s.
func ( interface{},  string) error {
	return ParseValue(reflect.ValueOf(), )
}

// ParseValue assigns a value to v by parsing s.
func ( reflect.Value,  string) error {
	// If we have a nil pointer then allocate a new object
	if .Kind() == reflect.Ptr && .IsNil() {
		if !.CanSet() {
			return errPtrNotSettable
		}

		.Set(reflect.New(.Type().Elem()))
	}

	// If it implements encoding.TextUnmarshaler then use that
	if ,  := .Interface().(encoding.TextUnmarshaler);  {
		return .UnmarshalText([]byte())
	}
	// If it's a value instead of a pointer, check that we can unmarshal it
	// via TextUnmarshaler as well
	if .CanAddr() {
		if ,  := .Addr().Interface().(encoding.TextUnmarshaler);  {
			return .UnmarshalText([]byte())
		}
	}

	// If we have a pointer then dereference it
	if .Kind() == reflect.Ptr {
		 = .Elem()
	}

	if !.CanSet() {
		return errNotSettable
	}

	// Switch on concrete type
	switch  := .Interface(); .(type) {
	case time.Duration:
		,  := time.ParseDuration()
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf())
		return nil
	case mail.Address:
		,  := mail.ParseAddress()
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf(*))
		return nil
	case net.HardwareAddr:
		,  := net.ParseMAC()
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf())
		return nil
	case url.URL:
		,  := url.Parse()
		if  != nil {
			return 
		}
		.Set(reflect.ValueOf(*))
		return nil
	}

	// Switch on kind so that we can handle derived types
	switch .Kind() {
	case reflect.String:
		.SetString()
	case reflect.Bool:
		,  := strconv.ParseBool()
		if  != nil {
			return 
		}
		.SetBool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		,  := strconv.ParseInt(, 0, .Type().Bits())
		if  != nil {
			return 
		}
		.SetInt()
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		,  := strconv.ParseUint(, 0, .Type().Bits())
		if  != nil {
			return 
		}
		.SetUint()
	case reflect.Float32, reflect.Float64:
		,  := strconv.ParseFloat(, .Type().Bits())
		if  != nil {
			return 
		}
		.SetFloat()
	default:
		return fmt.Errorf("cannot parse into %v", .Type())
	}
	return nil
}

// CanParse returns true if the type can be parsed from a string.
func ( reflect.Type) bool {
	// If it implements encoding.TextUnmarshaler then use that
	if .Implements(textUnmarshalerType) || reflect.PtrTo().Implements(textUnmarshalerType) {
		return true
	}

	// If we have a pointer then dereference it
	if .Kind() == reflect.Ptr {
		 = .Elem()
	}

	// Check for other special types
	switch  {
	case durationType, mailAddressType, macType, urlType:
		return true
	}

	// Fall back to checking the kind
	switch .Kind() {
	case reflect.Bool:
		return true
	case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
		reflect.Float32, reflect.Float64:
		return true
	}
	return false
}