Documentation ¶
Overview ¶
This package provides out-of-box conversion service.
Default Conversion Service ¶
You could use "NewDefaultConversionService()" function to construct an default implementation for "ConversionService" and "ConverterRegistry".
convSrv := types.NewDefaultConversionService()
Customized converter ¶
You could use "AddConverter()" method to register a converter between two "reflect.Type"s
r.AddConverter(reflect.TypeOf(v1), reflect.TypeOf(v2), your_converter)
Type of interface ¶
In some cases, you need the "reflect.Type" on a defined interface, you could use common/reflect."TypeOfInterface()" to hold the interface for reflection:
type DoSomething interface { Perform(int) GetData() string } var _t_YourType = oreflect.TypeOfInterface((*DoSomething)(nil)) // Checking if a type implements your interface if yourType.Implements(_t_YourType) { }
Index ¶
- func AddDefaultConverters(registry ConverterRegistry)
- func DoBinding(sourceObject interface{}, holder interface{})
- func HasBinding(holder interface{}) bool
- type Binding
- type Bytes16
- type ConversionService
- type Converter
- type ConverterRegistry
- type DefaultConversionService
- func (s *DefaultConversionService) AddConverter(sourceType reflect.Type, targetType reflect.Type, converter Converter)
- func (s *DefaultConversionService) CanConvert(sourceType reflect.Type, targetType reflect.Type) bool
- func (s *DefaultConversionService) ConvertTo(sourceObject interface{}, targetType reflect.Type) interface{}
- type FormattedConversionService
- type Formatter
- type FormatterRegistry
- type Parser
- type Printer
- type SupportBase64
- type Uuid
- type VarBytes
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddDefaultConverters ¶
func AddDefaultConverters(registry ConverterRegistry)
Adds additional converters:
String to satori/go.uuid.UUID
func DoBinding ¶
func DoBinding(sourceObject interface{}, holder interface{})
Convenient function to perform the binding
sourceObject - The source to be converted holder - The object implements "Binding" interface
This function would panic if the holder doesn't implement "Binding" interface.
func HasBinding ¶
func HasBinding(holder interface{}) bool
Checks if a object has implemented "Binding" interface
Types ¶
type Binding ¶
type Binding interface {
// Binds the content of source object into this object
Bind(sourceObject interface{})
}
Defines the binding interface to convert any object to implementing type
Example ¶
/* type MyBox struct { Name string } func (b *MyBox) Bind(source interface{}) { switch v := source.(type) { case int: b.Name = fmt.Sprintf("Name by number: %d", v) case string: b.Name = fmt.Sprintf("Name by string: %s", v) default: panic(fmt.Sprintf("Cannot be converted from value of type: %T", source)) } } */ box := &MyBox{} DoBinding(44, box) fmt.Println(box.Name) DoBinding("BC-908", box) fmt.Println(box.Name)
Output: Name by number: 44 Name by string: BC-908
Example (ConversionService) ¶
convSrv := NewDefaultConversionService() /* type MyBox struct { Name string } func (b *MyBox) Bind(source interface{}) { switch v := source.(type) { case int: b.Name = fmt.Sprintf("Name by number: %d", v) case string: b.Name = fmt.Sprintf("Name by string: %s", v) default: panic(fmt.Sprintf("Cannot be converted from value of type: %T", source)) } } */ // Gets the function of conversion and target type convertFunc, targetType := BindingToConverter(func() interface{} { return &MyBox{} }) convSrv.AddConverter(TypeOfInt, targetType, convertFunc) convSrv.AddConverter(TypeOfString, targetType, convertFunc) fmt.Println(convSrv.ConvertTo(89, targetType).(*MyBox).Name) fmt.Println(convSrv.ConvertTo("CP-091", targetType).(*MyBox).Name)
Output: Name by number: 89 Name by string: CP-091
type Bytes16 ¶
type Bytes16 [16]byte
func (*Bytes16) FromBase64 ¶
func (*Bytes16) FromVarBytes ¶
func (*Bytes16) MustFromBase64 ¶
func (*Bytes16) MustFromVarBytes ¶
func (*Bytes16) ToVarBytes ¶
type ConversionService ¶
type ConversionService interface { // Checks whether or not a type can be converted to another one CanConvert(sourceType reflect.Type, targetType reflect.Type) bool // Convert a variable to target type ConvertTo(sourceObject interface{}, targetType reflect.Type) interface{} }
Main interface provided by convsersion service
Example (CustomiedConverter) ¶
convSrv := NewDefaultConversionService() // import ot "github.com/fwtpe/owl-backend/common/reflect/types" convSrv.AddConverter( TypeOfInt8, TypeOfString, func(source interface{}) interface{} { return fmt.Sprintf("int8:%d", source) }, ) fmt.Printf("%s\n", convSrv.ConvertTo(int8(44), TypeOfString))
Output: int8:44
Example (Map) ¶
convSrv := NewDefaultConversionService() sourceMap := map[string]int32{ "Key1": 88, "Key2": 92, "Key3": 63, } // import ot "github.com/fwtpe/owl-backend/common/reflect/types" targetMap := convSrv.ConvertTo( sourceMap, reflect.MapOf( TypeOfString, TypeOfUint64, ), ).(map[string]uint64) fmt.Printf("%d, %d, %d\n", targetMap["Key1"], targetMap["Key2"], targetMap["Key3"])
Output: 88, 92, 63
Example (Slice) ¶
convSrv := NewDefaultConversionService() // import ot "github.com/fwtpe/owl-backend/common/reflect/types" sourceSlice := []string{"76", "38", "99"} targetSlice := convSrv.ConvertTo(sourceSlice, STypeOfInt).([]int) fmt.Printf("%#v\n", targetSlice)
Output: []int{76, 38, 99}
type Converter ¶
type Converter func(sourceObject interface{}) interface{}
General conversion function
func BindingToConverter ¶
Converts the Binding(with builder) to "Converter"
type ConverterRegistry ¶
type ConverterRegistry interface { // Adds a customized converter AddConverter(sourceType reflect.Type, targetType reflect.Type, converter Converter) }
Defines the registry for managing converters
type DefaultConversionService ¶
type DefaultConversionService struct {
// contains filtered or unexported fields
}
Default implementation for conversion service
Abstract ¶
There are two phases for conversion process:
1 - Use converters added by "AddConverter()" method(customized converters). 2 - Use build-in converters if nothing is matched on customized converters.
Build-in converters ¶
If target type is pointer, the converted object would be allocated by new().
If the target type is string, this service would use:
anyValue -> fmt.Sprintf("%v", anyValue)
If source type is string, following target type could be converted:
Int, Uint. Float and Bool
For any non-complex value(which is not array, slice, or channel), the value could be converted to:
Array: Puts the converted element to "[n]string { convertedV }" type -> [1]type Slice: Puts the converted element to "[]string { convertedV }". len(slice) == 1. cap(slice) == 1 type -> []type Channel: Send the converted element to "new(chan string, 1)" type -> chan type len() == 1
From array to slice(convertible element type)
[3]type -> []type(len == 3, cap == 3)
From array/slice to channel(convertible element type)
[3]type -> Puts every element in array to new(chan type, 3) []type { "v1", "v2" } -> Puts len([]type) elements to new(chan type, len([]type))
From channel to slice(convertible element type), this service would try to receive an element from channel(without blocking)
chan type -> []type chan type -> [n]type
WARNING: The value of channel would be put back.
If the target type is array and the len(source) > len(array), this service would **panic**.
// Panic []type { v1, v2 } -> [1]type
From a map to another map of different types: Both of the key and value of maps must be convertible
map[string]int -> map[int]string
The key of map, must obey the rules defined by go lang:
The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice. If the key type is an interface type, these comparison operators must be defined for the dynamic key values; failure will cause a run-time panic.
See map type: https://golang.org/ref/spec#Map_types
See comparison operator: https://golang.org/ref/spec#Comparison_operators
Otherwise, see https://golang.org/ref/spec#Conversions
Example ¶
convSrv := NewDefaultConversionService() stringV := convSrv.ConvertTo(45, TypeOfString) fmt.Printf("%T:%s\n", stringV, stringV)
Output: string:45
func NewDefaultConversionService ¶
func NewDefaultConversionService() *DefaultConversionService
Constructs a new instance of default implementation
func (*DefaultConversionService) AddConverter ¶
func (s *DefaultConversionService) AddConverter(sourceType reflect.Type, targetType reflect.Type, converter Converter)
Implements the interface "ConverterRegistry"
func (*DefaultConversionService) CanConvert ¶
func (s *DefaultConversionService) CanConvert(sourceType reflect.Type, targetType reflect.Type) bool
Implements the interface "ConversionService"
Only checks added converters(without processing of pointer)
func (*DefaultConversionService) ConvertTo ¶
func (s *DefaultConversionService) ConvertTo(sourceObject interface{}, targetType reflect.Type) interface{}
Implements the interface "ConversionService"
type FormattedConversionService ¶
type FormattedConversionService interface { ConversionService // Generates the string-representation of an object Print(sourceObject interface{}) string // Generates the string-representation of an object(with locale) PrintWithLocale(sourceObject interface{}, locale *time.Location) string // Converts the string value to target value Scan(stringValue string) interface{} // Converts the string value to target value(with locale) ScanWithLocale(stringValue string, locale *time.Location) interface{} }
Sub-type of ConversionService, which provides methods of "Print()" and "Scan()"...
type FormatterRegistry ¶
type FormatterRegistry interface { ConverterRegistry // Adds formatter with type of object AddFormatter(objectType reflect.Type, formatter Formatter) // Adds formatter by type of struct's field AddFormatterForField(field reflect.StructField, formatter Formatter) }
Sub-type of ConverterRegistry, with registering of formatter.