reflector

package
v0.0.0-...-157c9c8 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2024 License: GPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package reflector provides a number of helpers for working with reflection.

Index

Examples

Constants

View Source
const (
	// ErrParserSet is returned when reflect.Value.Set fails
	ErrParserSet = lerr.Str("could not set")
	// ErrExpectedPtr is returned if the type is not a pointer
	ErrExpectedPtr    = lerr.Str("expected ptr")
	ErrExpectedStruct = lerr.Str("expected struct")
)

Variables

This section is empty.

Functions

func CanElem

func CanElem(k reflect.Kind) bool

CanElem returns true if it is safe to call Elem on k.

func CanNil

func CanNil(k reflect.Kind) bool

CanNil reports wether k is a nilable kind.

func Elem

func Elem(t reflect.Type) (out reflect.Type, ok bool)

Elem calls t.Elem if it is safe to do so.

func IsNil

func IsNil(t reflect.Value) bool

IsNil reports whether its argument t is nil. Unlike the underlying t.IsNil, it will not panic.

Example
package main

import (
	"fmt"
	"reflect"

	"github.com/adamcolton/luce/util/reflector"
)

func main() {
	str := "test"
	strPtr := &str
	v := reflect.ValueOf(strPtr)
	fmt.Println(reflector.IsNil(v))

	strPtr = nil
	v = reflect.ValueOf(strPtr)
	fmt.Println(reflector.IsNil(v))

	v = reflect.ValueOf(123)
	// calling v.IsNil() would panic
	fmt.Println(reflector.IsNil(v))

}
Output:

false
true
false

func Make

func Make(t reflect.Type) reflect.Value

func ParserAdd

func ParserAdd[In, Out any](p Parser[In], fn func(Out, In) error)

func ReturnsErrCheck

func ReturnsErrCheck(returnVals []reflect.Value) error

ReturnsErrCheck checks the return values from a function call to see if the last value is an error.

Example
package main

import (
	"fmt"
	"reflect"

	"github.com/adamcolton/luce/util/reflector"
)

func main() {
	v := reflect.ValueOf(func(i int) (int, error) {
		if i > 0 {
			return i + 10, nil
		}
		return 0, fmt.Errorf("i should be > 0, got: %d", i)
	})

	args := []reflect.Value{
		reflect.ValueOf(10),
	}
	got := v.Call(args)
	err := reflector.ReturnsErrCheck(got)
	fmt.Println(err)

	args[0] = reflect.ValueOf(-1)
	got = v.Call(args)
	err = reflector.ReturnsErrCheck(got)
	fmt.Println(err)

}
Output:

<nil>
i should be > 0, got: -1

func Set

func Set(target, to reflect.Value) (out bool)

func ToType

func ToType(i any) reflect.Type

ToType returns reflect.Type unless it is already an instance reflect.Type.

Example
package main

import (
	"fmt"

	"github.com/adamcolton/luce/util/reflector"
)

func main() {
	t := reflector.ToType("test")
	fmt.Println("t is reflect.Type on", t.String())

	t2 := reflector.ToType(t)
	fmt.Println("t2 is reflect.Type on", t2.String())
}
Output:

t is reflect.Type on string
t2 is reflect.Type on string

func ToValue

func ToValue(i any) reflect.Value

ToValue returns reflect.Value of i unless it is already an instance of reflect.Value.

Example
package main

import (
	"fmt"

	"github.com/adamcolton/luce/util/reflector"
)

func main() {
	v := reflector.ToValue("test")
	fmt.Println("v is reflect.Value on", v.Kind())

	v2 := reflector.ToValue(v)
	fmt.Println("v2 is reflect.Value on", v2.Kind())
}
Output:

v is reflect.Value on string
v2 is reflect.Value on string

func Type

func Type[T any]() reflect.Type

Type creates a reflect.Type from the generic type without allocating memory. This is a wrapper around reflect.TypeOf((*T)(nil)).Elem().

Example
package main

import (
	"fmt"

	"github.com/adamcolton/luce/util/reflector"
)

func main() {
	t := reflector.Type[string]()
	fmt.Println("t is reflect.Type on", t.String())
}
Output:

t is reflect.Type on string

Types

type ErrParserNotFound

type ErrParserNotFound struct {
	Type reflect.Type
}

ErrParserNotFound is returned when a parser does not contain a given Type.

func (ErrParserNotFound) Error

func (err ErrParserNotFound) Error() string

Error fullfils the error interface.

type Method

type Method struct {
	// On is the type the Method is define on
	On reflect.Value
	// Method is the reflect.Method value for the method
	reflect.Method
	// Func value of the method.
	Func reflect.Value
}

Method captures the reflection values that are useful when doing reflection on a method.

func MethodOn

func MethodOn(on any, name string) *Method

MethodOn get a Method by name. The 'on' argument can be either an interface or a reflect.Value.

func (*Method) AssignTo

func (m *Method) AssignTo(fnPtr any) (success bool)

AssignTo attempts to assign this method to fnPtr. The value of success indicates if it worked.

Example
package main

import (
	"fmt"

	"github.com/adamcolton/luce/util/reflector"
)

type foo struct{}

func (foo) A(a, b int)                   {}
func (foo) Hello() string                { return "Hello" }
func (foo) Goodbye() string              { return "Goodbye" }
func (foo) AddExPt(name string) string   { return name + "!" }
func (foo) TwoArgs(first, second string) {}

func main() {
	var f foo
	// foo has methods:
	// * A(a, b int)
	// * Hello() string
	// * Goodbye() string
	// * AddExPt(name string) string
	// * TwoArgs(first, second string)

	var fn func(string) string
	for _, m := range reflector.MethodsOn(f) {
		if m.AssignTo(&fn) {
			break
		}
	}

	fmt.Println(fn("goodbye"))
}
Output:

goodbye!

type Methods

type Methods []*Method

Methods on a single value - at least that's the intention.

func MethodsOn

func MethodsOn(i any) Methods

MethodsOn returns all the methods on the interface provided.

Example
package main

import (
	"fmt"

	"github.com/adamcolton/luce/util/reflector"
)

type foo struct{}

func (foo) A(a, b int)                   {}
func (foo) Hello() string                { return "Hello" }
func (foo) Goodbye() string              { return "Goodbye" }
func (foo) AddExPt(name string) string   { return name + "!" }
func (foo) TwoArgs(first, second string) {}

func main() {
	var f foo
	// foo has methods:
	// * A(a, b int)
	// * Hello() string
	// * Goodbye() string
	// * AddExPt(name string) string
	// * TwoArgs(first, second string)

	m := reflector.MethodOn(f, "Hello")
	fmt.Println(m.Func.Call(nil)[0])
}
Output:

Hello

func (Methods) Funcs

func (ms Methods) Funcs() []any

Funcs returns just the Func values of the Methods. This can be useful because the On and Method fields are generally only useful for filtering and the Func value can be invoked with .Call - so after filtering, this allows the Func values to be used.

Example
package main

import (
	"fmt"
	"sort"

	"github.com/adamcolton/luce/util/reflector"
)

type foo struct{}

func (foo) A(a, b int)                   {}
func (foo) Hello() string                { return "Hello" }
func (foo) Goodbye() string              { return "Goodbye" }
func (foo) AddExPt(name string) string   { return name + "!" }
func (foo) TwoArgs(first, second string) {}

func main() {
	var f foo
	// foo has methods:
	// * A(a, b int)
	// * Hello() string
	// * Goodbye() string
	// * AddExPt(name string) string
	// * TwoArgs(first, second string)

	var seeking = reflector.Type[func(foo) string]()
	var ms reflector.Methods
	for _, m := range reflector.MethodsOn(f) {
		// note: comparing to Method.Type not Func.Type().
		if m.Type == seeking {
			ms = append(ms, m)
		}
	}
	sort.Slice(ms, func(i, j int) bool {
		return ms[i].Name > ms[j].Name
	})

	for _, f := range ms.Funcs() {
		fmt.Println(f.(func() string)())
	}

}
Output:

Hello
Goodbye

type Parser

type Parser[T any] map[reflect.Type]func(reflect.Value, T) error

Parser is used to parse one data type into many. The most common types for T will be string or []byte.

func (Parser[T]) Parse

func (p Parser[T]) Parse(i any, t T) error

Parse 't' into interface 'i' using the Parser.

func (Parser[T]) ParseFieldName

func (p Parser[T]) ParseFieldName(i any, name string, t T) error

func (Parser[T]) ParseValue

func (p Parser[T]) ParseValue(v reflect.Value, t T) error

Parse 't' into 'v' using the Parser.

func (Parser[T]) ParseValueFieldName

func (p Parser[T]) ParseValueFieldName(v reflect.Value, name string, t T) error

type ParserFunc

type ParserFunc[In, Out any] func(Out, In) error

func (ParserFunc[In, Out]) Parser

func (pf ParserFunc[In, Out]) Parser(v reflect.Value, in In) (err error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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