elastic

package module
v0.0.0-...-1788683 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2020 License: MIT Imports: 4 Imported by: 1

README

elastic

Build Status GoDoc

Converts go types no matter what

elastic is a simple library that converts any type to another the best way possible. This is useful when the type is only known at run-time, which usually happens when serializing data. elastic allows your code to be flexible regarding type conversion if that is what you're looking for.

It is also capable of seeing through alias types and converting slices and maps to and from other types of slices and maps, providing there is some logical way to convert them.

Default conversion can be overridden by providing custom conversion functions for specific types. Struct types can also implement the ConverterTo interface to help with conversion to and from specific types.

Quick examples:

convert value types:
	// note that using elastic wouldn't make sense if you are certain
    // f is a float64 at compile time.
    var f interface{} = float64(5.5)
	var i int
    
    err := elastic.Set(&i, f)
	if err != nil {
		log.Fatal(f)
	}

	fmt.Println(i) // prints 5
convert slices:
	var ints []int
	err = elastic.Set(&ints, []interface{}{1, 2, 3, "4", float64(5), 6})
	if err != nil {
		log.Fatal(f)
	}

	fmt.Println(ints) // prints [1 2 3 4 5 6]
convert maps:
	someMap := map[string]interface{}{
		"1": "uno",
		"2": "dos",
		"3": "tres",
	}

	intmap := make(map[int]string)
	err = elastic.Set(&intmap, someMap)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(intmap) // prints map[1:uno 2:dos 3:tres]

Simple API:

elastic.Convert()

Converts the passed value to the target type

Syntax:

elastic.Convert(source interface{}, targetType reflect.Type) (interface{}, error)

  • source: value to convert
  • targetType the type you want to convert source to
Returns

The converted value or an error if it fails.

elastic.Set()

Sets the given variable to the passed value

Syntax:

elastic.Set(target, source interface{}) error

  • target: value to set. Must be a pointer.
  • source the value to convert
Returns

Only an error if it fails.

Advanced API:

You can create different instances of the elastic conversion engine so that you can customize conversions independently

elastic.New()

Returns a new conversion engine. It has a .Set() and .Convert() as above that will work according to the rules set for this engine

AddSourceConverter() and AddTargetConverter()

Registers a conversion function for the given type, either when the type is found on the source side or the target side.

These are useful when you do not control the type you whish to make convertible

Syntax:

engine.AddSourceConverter(sourceType reflect.Type, f ConverterFunc)

  • sourceType: type you want to set a custom conversion function for
  • f: Conversion function to invoke when this type is found as a source

engine.AddTargetConverter(targetType reflect.Type, f ConverterFunc)

  • targetType: type you want to set a custom conversion function for
  • f: Conversion function to invoke when this type is found as a target

The value returned by your function does not have to be exactly of type targetType. For example if a float64 is requested and you return an integer, elastic will deal with it.

Example:
package main

type Vector struct {
	X float64
	Y float64
}

func main() {

	// Add a custom converter to convert Vector to float64 or int
	// (Calculates the modulus of the vector)
	elastic.Default.AddSourceConverter(reflect.TypeOf(Vector{}), func(source interface{}, targetType reflect.Type) (interface{}, error) {
		vector := source.(Vector)
		switch targetType.Kind() {
		case reflect.Float64, reflect.Int:
			return math.Sqrt(float64(vector.X*vector.X) + float64(vector.Y*vector.Y)), nil
		case reflect.String:
			return fmt.Sprintf("(%g, %g)", vector.X, vector.Y), nil
		}
		return nil, elastic.ErrNoConversionAvailable

	})

	v := Vector{
		X: 3.0,
		Y: 4.0,
	}

	f, err = elastic.Convert(v, reflect.TypeOf(float64(0)))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(f) // prints 5

	var s string
	elastic.Set(&s, v)
	fmt.Println(s) // prints (3, 4)

}

ConverterTo interface

type ConverterTo interface {
	ConvertTo(targetType reflect.Type) (interface{}, error)
}

Implement this interface in your type to provide conversion to another types. This function will be invoked every time your type is on the right-hand side of a conversion. The value returned by your function does not have to be exactly of type targetType. For example if a float64 is requested and you return an integer, elastic will deal with it.

Example:
type Vector struct {
	X float64
	Y float64
}

func (v *Vector) ConvertTo(targetType reflect.Type) (interface{}, error) {
		switch targetType.Kind() {
		case reflect.Float64, reflect.Int:
			return math.Sqrt(float64(v.X*v.X) + float64(v.Y*v.Y)), nil
		case reflect.String:
			return fmt.Sprintf("(%g, %g)", v.X, v.Y), nil
		}
		return nil, elastic.ErrNoConversionAvailable
}

func main() {
	v := Vector{
		X: 3.0,
		Y: 4.0,
	}
	
	var i int
	elastic.Set(&i, v)
	fmt.Println(i) // prints 5

	var s string
	elastic.Set(&s, v)
	fmt.Println(s) // prints (3, 4)
}


Documentation

Index

Constants

This section is empty.

Variables

View Source
var Default = New()

Default is a default conversion engine

View Source
var ErrExpectedPointer = errors.New("Expected pointer")

ErrExpectedPointer is returned when the function expects a pointer parameter

View Source
var ErrIncompatibleType = errors.New("Incompatible types")

ErrIncompatibleType is returned when it is impossible to convert a type to another

View Source
var ErrNoConversionAvailable = errors.New("No conversion available")

ErrNoConversionAvailable is returned by any ConverterFunc when it does not know how to convert the passed values

Functions

func Convert

func Convert(source interface{}, targetType reflect.Type) (interface{}, error)

Convert attempts to convert the source value to the given target type using the default engine if it does not fail, the returned value is guaranteed to be of the target type

func Set

func Set(target, source interface{}) error

Set sets the given target pointer to source value using the default engine performing any type conversion necessary

Types

type ConverterEngine

type ConverterEngine struct {
	// contains filtered or unexported fields
}

ConverterEngine keeps conversion configurations

func New

func New() *ConverterEngine

New instantiates a new Converter Engine

func (*ConverterEngine) AddInterfaceConverter

func (ce *ConverterEngine) AddInterfaceConverter(interfaceType reflect.Type, f ConverterFunc)

AddInterfaceConverter adds a converion function for types that match the given interface (experimental)

func (*ConverterEngine) AddSourceConverter

func (ce *ConverterEngine) AddSourceConverter(sourceType reflect.Type, f ConverterFunc)

AddSourceConverter adds a source conversion function to the engine that knows how to convert the source type to some targets

func (*ConverterEngine) AddTargetConverter

func (ce *ConverterEngine) AddTargetConverter(targetType reflect.Type, f ConverterFunc)

AddTargetConverter adds a target conversion function to the engine that knows how to convert the target type from some sources

func (*ConverterEngine) Convert

func (ce *ConverterEngine) Convert(source interface{}, targetType reflect.Type) (interface{}, error)

Convert attempts to convert the source value to the given target type if it does not fail, the returned value is guaranteed to be of the target type

func (*ConverterEngine) Set

func (ce *ConverterEngine) Set(target, source interface{}) error

Set sets the given target pointer to sourcevalue, performing any type conversion necessary

type ConverterFunc

type ConverterFunc func(source interface{}, targetType reflect.Type) (interface{}, error)

ConverterFunc is called to override default conversions

type ConverterTo

type ConverterTo interface {
	ConvertTo(targetType reflect.Type) (interface{}, error)
}

ConverterTo interface allows you to define how your type should convert to others

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL