rawconv

package module
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2024 License: BSD-3-Clause Imports: 7 Imported by: 2

README

rawconv

Latest release Build status Go Report Card Documentation

Package rawconv implements conversions to and from raw string representations of any (custom) data types in Go.

Included features are:

  • Convert from raw string to out of the box supported types, and vice versa:
    • string, rune
    • bool
    • int, int8, int16, int32, int64
    • uint, uint8, uint16, uint32, uint64
    • float32, float64
    • complex64, complex128
    • array, slice
    • map
    • time.Duration
    • url.URL
    • encoding.TextUnmarshaler, encoding.TextMarshaler
  • Globally add support for your own custom types
  • Or isolate support for your own custom types via Marshaler and Unmarshaler instances

go get github.com/go-pogo/rawconv
import "github.com/go-pogo/rawconv"

Usage

Below example demonstrates how to unmarshal a raw string into a time.Duration type using Unmarshal.

package main

import (
    "fmt"
    "github.com/go-pogo/rawconv"
    "time"
)

func main() {
    var duration time.Duration
    if err := rawconv.Unmarshal("1h2m3s", &duration); err != nil {
        panic(err)
    }

    fmt.Println(duration)
    // Output: 1h2m3s
}

Array, slice and map conversions

Conversions to array, slice or map are done by splitting the raw string. The separator can be set via the Options type and defaults to DefaultItemsSeparator. For maps there is also a separator for the key-value pairs, which defaults to DefaultKeyValueSeparator. Values within the array, slice, or map are unmarshaled using the called Unmarshaler. This is also done for keys of maps.

package main

import (
    "fmt"
    "github.com/go-pogo/rawconv"
    "reflect"
)

func main() {
	var u rawconv.Unmarshaler
	u.ItemsSeparator = ";"

	var list []string
	if err := u.Unmarshal("foo;bar", reflect.ValueOf(&list)); err != nil {
		panic(err)
	}

	fmt.Println(list)
	// Output: [foo bar]
}

Nested arrays, slices and maps are not supported.

Structs

This package does not contain any logic for traversing struct types, because the implementation would really depend on the use case. However, it is possible to incorporate this package in your own struct unmarshaling logic.

Custom types

Custom types are supported in two ways; by implementing the encoding.TextUnmarshaler and/or encoding.TextMarshaler interfaces, or by registering a MarshalFunc with RegisterMarshalFunc and/or an UnmarshalFunc with RegisterUnmarshalFunc. If you do not wish to globally expose your MarshalFunc orUnmarshalFunc implementations, it is possible to register them to a new Marshaler or Unmarshaler and use those instances in your application instead.

package main

import (
    "github.com/davecgh/go-spew/spew"
    "github.com/go-pogo/rawconv"
    "reflect"
)

func main() {
    type myType struct {
        something string
    }

    var u rawconv.Unmarshaler
    u.Register(reflect.TypeOf(myType{}), func(val rawconv.Value, dest any) error {
        mt := dest.(*myType)
        mt.something = val.String()
        return nil
    })

    var target myType
    if err := u.Unmarshal("some value", reflect.ValueOf(&target)); err != nil {
        panic(err)
    }

    spew.Dump(target)
    // Output:
    // (rawconv.myType) {
    //  something: (string) (len=10) "some value"
    // }
}

Documentation

Additional detailed documentation is available at pkg.go.dev

Created with

License

Copyright © 2022-2024 Roel Schut. All rights reserved.

This project is governed by a BSD-style license that can be found in the LICENSE file.

Documentation

Overview

Package rawconv implements conversions to and from raw string representations of any (custom) data type in Go.

Basic conversions

Out of the box, this package supports all logical base types and some common types:

  • string, rune
  • bool
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • complex64, complex128
  • array, slice
  • map
  • time.Duration
  • url.URL
  • encoding.TextUnmarshaler, encoding.TextMarshaler

Array, slice and map conversions

Conversions to array, slice or map are done by splitting the raw string. The separator can be set via the Options type and defaults to DefaultItemsSeparator. For maps there is also a separator for the key-value pairs, which defaults to DefaultKeyValueSeparator.

Values within the array, slice, or map are unmarshaled using the called Unmarshaler. This is also done for keys of maps.

> Nested arrays, slices and maps are not supported.

Structs

This package does not contain any logic for traversing struct types, because the implementation would really depend on the use case. However, it is possible to incorporate this package in your own struct unmarshaling logic.

Custom types

Custom types are supported in two ways; by implementing the encoding.TextUnmarshaler and/or encoding.TextMarshaler interfaces, or by registering a MarshalFunc with RegisterMarshalFunc and/or an UnmarshalFunc with RegisterUnmarshalFunc.

If you do not wish to globally expose your MarshalFunc or UnmarshalFunc implementations, it is possible to register them to a new Marshaler and/or Unmarshaler and use those instances in your application instead.

Index

Examples

Constants

View Source
const (
	ErrPointerExpected    errors.Msg = "expected a non-nil pointer to a value"
	ErrUnmarshalNested    errors.Msg = "cannot unmarshal nested array/slice/map"
	ErrUnableToSet        errors.Msg = "unable to set value"
	ErrUnableToAddr       errors.Msg = "unable to addr value"
	ErrRuneTooManyChars   errors.Msg = "too many characters"
	ErrArrayTooManyValues errors.Msg = "too many values"
	ErrMapInvalidFormat   errors.Msg = "invalid map format"

	// ImplementationError indicates the programmer made a mistake implementing
	// the package and this should be fixed.
	ImplementationError errors.Kind = "implementation error"
)
View Source
const (
	ParseError      errors.Kind = "parse error"
	ValidationError errors.Kind = "validation error"
)
View Source
const (
	DefaultItemsSeparator    = ","
	DefaultKeyValueSeparator = "="
)
View Source
const ErrMarshalNested errors.Msg = "cannot marshal nested array/slice/map"

Variables

This section is empty.

Functions

func RegisterMarshalFunc

func RegisterMarshalFunc(typ reflect.Type, fn MarshalFunc)

RegisterMarshalFunc registers the MarshalFunc for typ, making it globally available for Marshal, MarshalValue, MarshalReflect and any Marshaler.

func RegisterUnmarshalFunc

func RegisterUnmarshalFunc(typ reflect.Type, fn UnmarshalFunc)

RegisterUnmarshalFunc registers the UnmarshalFunc for typ, making it globally available for Unmarshal and any Unmarshaler.

func Unmarshal

func Unmarshal(val Value, v any) error

Unmarshal parses Value and stores the result in the value pointed to by v. If v is nil or not a pointer, Unmarshal returns an ErrPointerExpected error. If v is not a supported type an UnsupportedTypeError is returned. By default, the following types are supported:

  • string
  • bool
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • complex64, complex128
  • array, slice
  • map
  • time.Duration
  • url.URL
  • encoding.TextUnmarshaler

Use RegisterUnmarshalFunc to add additional (custom) types.

Example

Below example demonstrates how to unmarshal a raw string into a time.Duration type using Unmarshal.

var duration time.Duration
if err := Unmarshal("1h2m3s", &duration); err != nil {
	panic(err)
}

fmt.Println(duration)
Output:

1h2m3s

Types

type MarshalFunc

type MarshalFunc func(v any) (string, error)

func GetMarshalFunc

func GetMarshalFunc(typ reflect.Type) MarshalFunc

GetMarshalFunc returns the globally registered MarshalFunc for reflect.Type typ or nil if there is none registered with RegisterMarshalFunc.

func (MarshalFunc) Exec

func (fn MarshalFunc) Exec(val reflect.Value) (Value, error)

Exec executes the MarshalFunc for the given reflect.Value.

type Marshaler

type Marshaler struct {
	Options
	// contains filtered or unexported fields
}

Marshaler is a type which can marshal any reflect.Value to its raw string representation as long as it's registered with Register. It wil always fallback to the global Marshaler when a type is not registered.

Example
var m Marshaler
target, _ := url.ParseRequestURI("https://example.com")
val, err := m.Marshal(reflect.ValueOf(target))
if err != nil {
	panic(err)
}

fmt.Println(val.String())
Output:

https://example.com

func (*Marshaler) Func

func (m *Marshaler) Func(typ reflect.Type) MarshalFunc

Func returns the (globally) registered MarshalFunc for reflect.Type typ or nil if there is none registered with Register or RegisterMarshalFunc.

func (*Marshaler) Marshal

func (m *Marshaler) Marshal(val reflect.Value) (Value, error)

Marshal returns the string representation of the value. If the underlying reflect.Value is nil, it returns an empty string.

func (*Marshaler) Register

func (m *Marshaler) Register(typ reflect.Type, fn MarshalFunc) *Marshaler

Register the MarshalFunc for typ but only for this Marshaler.

type Options added in v0.5.1

type Options struct {
	ItemsSeparator    string // ,
	KeyValueSeparator string // =
}

type UnmarshalFunc

type UnmarshalFunc func(val Value, dest any) error

UnmarshalFunc is a function which can unmarshal a Value to any type. Argument dest is always a pointer to the value to unmarshal to.

func GetUnmarshalFunc

func GetUnmarshalFunc(typ reflect.Type) UnmarshalFunc

GetUnmarshalFunc returns the globally registered UnmarshalFunc for reflect.Type typ or nil if there is none registered with RegisterUnmarshalFunc.

func (UnmarshalFunc) Exec

func (fn UnmarshalFunc) Exec(v Value, dest reflect.Value) error

Exec executes the UnmarshalFunc by taking the address of dest, and passing it as an interface to UnmarshalFunc. It will return an error when the address of reflect.Value dest cannot be taken, or when it is unable to set. Any error returned by UnmarshalFunc is wrapped with ParseError.

type Unmarshaler

type Unmarshaler struct {
	Options
	// contains filtered or unexported fields
}

Unmarshaler is a type which can unmarshal a Value to any type that's registered with Register. It wil always fallback to the global Unmarshaler when a type is not registered.

Example
var u Unmarshaler
var target *url.URL
if err := u.Unmarshal("https://example.com", reflect.ValueOf(&target)); err != nil {
	panic(err)
}

fmt.Println(target.String())
Output:

https://example.com

func (*Unmarshaler) Func

func (u *Unmarshaler) Func(typ reflect.Type) UnmarshalFunc

Func returns the (globally) registered UnmarshalFunc for reflect.Type typ or nil if there is none registered with Register or RegisterUnmarshalFunc.

func (*Unmarshaler) Register

func (u *Unmarshaler) Register(typ reflect.Type, fn UnmarshalFunc) *Unmarshaler

Register the UnmarshalFunc for typ but only for this Unmarshaler.

Example
type myType struct {
	something string
}

var u Unmarshaler
u.Register(reflect.TypeOf(myType{}), func(val Value, dest any) error {
	mt := dest.(*myType)
	mt.something = val.String()
	return nil
})

var target myType
if err := u.Unmarshal("some value", reflect.ValueOf(&target)); err != nil {
	panic(err)
}

spew.Dump(target)
Output:

(rawconv.myType) {
 something: (string) (len=10) "some value"
}

func (*Unmarshaler) Unmarshal

func (u *Unmarshaler) Unmarshal(val Value, v reflect.Value) error

Unmarshal tries to unmarshal Value to a supported type which matches the type of v, and sets the parsed value to it. See Unmarshal for additional details.

Example
var u Unmarshaler
u.ItemsSeparator = ";"

var list []string
if err := u.Unmarshal("foo;bar", reflect.ValueOf(&list)); err != nil {
	panic(err)
}

fmt.Println(list)
Output:

[foo bar]

type UnsupportedTypeError

type UnsupportedTypeError struct {
	Type reflect.Type
}

func (*UnsupportedTypeError) Error

func (e *UnsupportedTypeError) Error() string

func (*UnsupportedTypeError) Is

func (e *UnsupportedTypeError) Is(err error) bool

type Value

type Value string

Value is a textual representation of a raw value which is able to cast itself to any of the supported types using its corresponding method.

boolVal, err := rawconv.Value("true").Bool()

func Marshal

func Marshal(v any) (Value, error)

Marshal formats the value pointed to by v to a raw string Value. If v is not a supported type an UnsupportedTypeError is returned. By default, the following types are supported:

  • encoding.TextMarshaler
  • string
  • bool
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • float32, float64
  • complex64, complex128
  • array, slice
  • map
  • time.Duration
  • url.URL

Use RegisterMarshalFunc to add additional (custom) types.

Example
duration := time.Hour + (time.Minute * 2) + (time.Second * 3)
val, err := Marshal(duration)
if err != nil {
	panic(err)
}

fmt.Println(val.String())
Output:

1h2m3s

func ValueFromBool added in v0.5.0

func ValueFromBool(v bool) Value

ValueFromBool encodes v to a Value using strconv.FormatBool.

func ValueFromComplex128 added in v0.5.0

func ValueFromComplex128(v complex128) Value

ValueFromComplex128 encodes v to a Value using strconv.FormatComplex.

func ValueFromComplex64 added in v0.5.0

func ValueFromComplex64(v complex64) Value

ValueFromComplex64 encodes v to a Value using strconv.FormatComplex.

func ValueFromFloat32 added in v0.5.0

func ValueFromFloat32(v float32) Value

ValueFromFloat32 encodes v to a Value using strconv.FormatFloat.

func ValueFromFloat64 added in v0.5.0

func ValueFromFloat64(v float64) Value

ValueFromFloat64 encodes v to a Value using strconv.FormatFloat.

func ValueFromInt added in v0.5.0

func ValueFromInt(v int) Value

ValueFromInt encodes v to a Value using strconv.FormatInt.

func ValueFromInt16 added in v0.5.0

func ValueFromInt16(v int16) Value

ValueFromInt16 encodes v to a Value using strconv.FormatInt.

func ValueFromInt32 added in v0.5.0

func ValueFromInt32(v int32) Value

ValueFromInt32 encodes v to a Value using strconv.FormatInt.

func ValueFromInt64 added in v0.5.0

func ValueFromInt64(v int64) Value

ValueFromInt64 encodes v to a Value using strconv.FormatInt.

func ValueFromInt8 added in v0.5.0

func ValueFromInt8(v int8) Value

ValueFromInt8 encodes v to a Value using strconv.FormatInt.

func ValueFromUint added in v0.5.0

func ValueFromUint(v uint) Value

ValueFromUint encodes v to a Value using strconv.FormatUint.

func ValueFromUint16 added in v0.5.0

func ValueFromUint16(v uint16) Value

ValueFromUint16 encodes v to a Value using strconv.FormatUint.

func ValueFromUint32 added in v0.5.0

func ValueFromUint32(v uint32) Value

ValueFromUint32 encodes v to a Value using strconv.FormatUint.

func ValueFromUint64 added in v0.5.0

func ValueFromUint64(v uint64) Value

ValueFromUint64 encodes v to a Value using strconv.FormatUint.

func ValueFromUint8 added in v0.5.0

func ValueFromUint8(v uint8) Value

ValueFromUint8 encodes v to a Value using strconv.FormatUint.

func (Value) Bool

func (v Value) Bool() (bool, error)

Bool tries to parse Value as a bool using strconv.ParseBool. It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. Any other value returns an error.

func (Value) BoolVar

func (v Value) BoolVar(p *bool) (err error)

BoolVar sets the value p points to using Bool.

func (Value) Bytes

func (v Value) Bytes() []byte

Bytes returns Value as raw bytes.

func (Value) BytesVar

func (v Value) BytesVar(p *[]byte)

BytesVar sets the value p points to, to Value as raw bytes.

func (Value) Complex128

func (v Value) Complex128() (complex128, error)

Complex128 tries to parse Value as a complex128 using strconv.ParseComplex.

func (Value) Complex128Var

func (v Value) Complex128Var(p *complex128) (err error)

Complex128Var sets the value p points to using Complex128.

func (Value) Complex64

func (v Value) Complex64() (complex64, error)

Complex64 tries to parse Value as a complex64 using strconv.ParseComplex.

func (Value) Complex64Var

func (v Value) Complex64Var(p *complex64) (err error)

Complex64Var sets the value p points to using Complex64.

func (Value) Duration

func (v Value) Duration() (time.Duration, error)

Duration tries to parse Value as a time.Duration using time.ParseDuration.

func (Value) DurationVar

func (v Value) DurationVar(p *time.Duration) (err error)

DurationVar sets the value p points to using Duration.

func (Value) Float32

func (v Value) Float32() (float32, error)

Float32 tries to parse Value as a float32 using strconv.ParseFloat.

func (Value) Float32Var

func (v Value) Float32Var(p *float32) (err error)

Float32Var sets the value p points to using Float32.

func (Value) Float64

func (v Value) Float64() (float64, error)

Float64 tries to parse Value as a float64 using strconv.ParseFloat.

func (Value) Float64Var

func (v Value) Float64Var(p *float64) (err error)

Float64Var sets the value p points to using Float64.

func (Value) GoString

func (v Value) GoString() string

func (Value) Int

func (v Value) Int() (int, error)

Int tries to parse Value as an int using strconv.ParseInt.

func (Value) Int16

func (v Value) Int16() (int16, error)

Int16 tries to parse Value as an int16 using strconv.ParseInt.

func (Value) Int16Var

func (v Value) Int16Var(p *int16) (err error)

Int16Var sets the value p points to using Int16.

func (Value) Int32

func (v Value) Int32() (int32, error)

Int32 tries to parse Value as an int32 using strconv.ParseInt.

func (Value) Int32Var

func (v Value) Int32Var(p *int32) (err error)

Int32Var sets the value p points to using Int32.

func (Value) Int64

func (v Value) Int64() (int64, error)

Int64 tries to parse Value as an int64 using strconv.ParseInt.

func (Value) Int64Var

func (v Value) Int64Var(p *int64) (err error)

Int64Var sets the value p points to using Int64.

func (Value) Int8

func (v Value) Int8() (int8, error)

Int8 tries to parse Value as an int8 using strconv.ParseInt.

func (Value) Int8Var

func (v Value) Int8Var(p *int8) (err error)

Int8Var sets the value p points to using Int8.

func (Value) IntVar

func (v Value) IntVar(p *int) (err error)

IntVar sets the value p points to using Int.

func (Value) IsEmpty

func (v Value) IsEmpty() bool

IsEmpty indicates if Value is an empty string.

func (Value) Rune added in v0.5.2

func (v Value) Rune() rune

Rune returns the first rune of Value.

func (Value) RuneVar added in v0.5.2

func (v Value) RuneVar(p *rune)

RuneVar sets the value p points to, to the first rune of Value.

func (Value) String

func (v Value) String() string

String returns Value as a raw string.

func (Value) StringVar

func (v Value) StringVar(p *string)

StringVar sets the value p points to, to Value as raw string.

func (Value) Uint

func (v Value) Uint() (uint, error)

Uint tries to parse Value as an uint using strconv.ParseUint

func (Value) Uint16

func (v Value) Uint16() (uint16, error)

Uint16 tries to parse Value as an uint16 using strconv.ParseUint.

func (Value) Uint16Var

func (v Value) Uint16Var(p *uint16) (err error)

Uint16Var sets the value p points to using Uint16.

func (Value) Uint32

func (v Value) Uint32() (uint32, error)

Uint32 tries to parse Value as an uint32 using strconv.ParseUint.

func (Value) Uint32Var

func (v Value) Uint32Var(p *uint32) (err error)

Uint32Var sets the value p points to using Uint32.

func (Value) Uint64

func (v Value) Uint64() (uint64, error)

Uint64 tries to parse Value as an uint64 using strconv.ParseUint.

func (Value) Uint64Var

func (v Value) Uint64Var(p *uint64) (err error)

Uint64Var sets the value p points to using Uint64.

func (Value) Uint8

func (v Value) Uint8() (uint8, error)

Uint8 tries to parse Value as an uint8 using strconv.ParseUint.

func (Value) Uint8Var

func (v Value) Uint8Var(p *uint8) (err error)

Uint8Var sets the value p points to using Uint8.

func (Value) UintVar

func (v Value) UintVar(p *uint) (err error)

UintVar sets the value p points to using Uint.

func (Value) Url

func (v Value) Url() (*url.URL, error)

Url tries to parse Value as an *url.URL using url.ParseRequestURI.

func (Value) UrlVar

func (v Value) UrlVar(p *url.URL) error

UrlVar sets the value p points to using Url.

Jump to

Keyboard shortcuts

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