tinyreflect

package module
v0.0.44 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2025 License: MIT Imports: 2 Imported by: 1

README

tinyreflect

Project Badges

Minimal Go reflect package from reflectlite, WebAssembly and TinyGo destination

Why TinyReflect?

Go's WebAssembly potential is incredible, but traditional applications face a critical challenge: massive binary sizes that make web deployment impractical.

The Problem

Every Go project needs reflection capabilities for JSON operations, struct field access, and dynamic type handling - but importing the standard library reflect package creates significant binary bloat that hurts:

  • 🌐 Web app performance - Slow loading times and poor user experience
  • 📱 Edge deployment - Resource constraints on small devices
  • 🚀 Distribution efficiency - Large binaries for simple operations
The Solution

TinyReflect replaces the standard library reflect package with ultra-minimal, focused implementations that deliver:

  • 🏆 Dramatically smaller binaries - Significant size reduction for WebAssembly through maximum code reuse
  • Full TinyGo compatibility - No compilation issues or warnings
  • 🎯 Predictable performance - No hidden allocations or overhead
  • 🔧 Minimal API - Only essential operations for basic JSON-like data handling
  • 🌍 Multilingual error handling - Integrated with tinystring's error system
  • ♻️ Maximum code reuse - Leverages tinystring's type detection to minimize duplication
Supported Types (Minimalist Approach)

TinyReflect intentionally supports only a minimal set of types to keep binary size small:

✅ Supported Types:

  • Basic types: string, bool
  • All numeric types: int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64
  • All basic slices: []string, []bool, []byte, []int, []int8, []int16, []int32, []int64, []uint, []uint8, []uint16, []uint32, []uint64, []float32, []float64
  • Structs: Only with supported field types
  • Struct slices: []struct{...} where all fields are supported types
  • Maps: map[K]V where K and V are supported types only
  • Map slices: []map[K]V where K and V are supported types only
  • Pointers: Only to supported types above

❌ Unsupported Types:

  • interface{}, chan, func
  • complex64, complex128
  • uintptr, unsafe.Pointer (used internally only)
  • Arrays (different from slices)
  • Nested complex types beyond supported scope

This focused approach ensures minimal code size while covering the most common JSON-like data operations including simple structs.

type User struct { u := User{"Alice", 42} v := tinyreflect.ValueOf(u) t := v.Type() id := t.StructID()

Minimal API usage

import "github.com/cdvelop/tinyreflect"

type User struct {
    Name string
    Age  int
}

u := User{"Alice", 42}
v := tinyreflect.ValueOf(u)
t := v.Type()

// Iterate fields and get name and value
num, _ := t.NumField()
for i := 0; i < num; i++ {
    name, _ := t.NameByIndex(i)
    field, _ := v.Field(i)
    value, _ := field.Interface()
    // name: field name, value: field value
}

// Unique type identifier (alternative to struct name)
id := t.StructID()
Minimal public API
  • ValueOf(any) Value — Create a reflected value.
  • Value.Type() *Type — Get the reflected type.
  • Value.Field(i int) (Value, error) — Get the i-th field of a struct value.
  • Value.Interface() (any, error) — Get the value as interface{}.
  • Type.NumField() (int, error) — Number of fields in a struct.
  • Type.NameByIndex(i int) (string, error) — Name of the i-th field.
  • Type.Field(i int) (StructField, error) — Info about the i-th field.
  • Type.Kind() Kind — Base type (struct, int, string, etc).
  • Type.StructID() uint32 — Unique identifier for the struct type.

No functions related to methods, interfaces, struct names, or advanced reflection are exposed. The API is deliberately minimal and robust against misuse.

Important: Reflection Limitations in TinyGo

Note: TinyReflect cannot obtain the textual name of a struct (like "Customer") in TinyGo, because TinyGo removes these metadata from the binary. See docs/LIMITATIONS_REFLECT_TINYGO.md for a detailed technical explanation and recommended alternatives.


Contributing

Documentation

Index

Constants

View Source
const (
	KindDirectIface Kind = 1 << 5
	KindMask        Kind = (1 << 5) - 1
)

Essential constants for type operations

Variables

This section is empty.

Functions

func NoEscape added in v0.0.13

func NoEscape(p unsafe.Pointer) unsafe.Pointer

NoEscape hides the pointer p from escape analysis, preventing it from escaping to the heap. It compiles down to nothing.

WARNING: This is very subtle to use correctly. The caller must ensure that it's truly safe for p to not escape to the heap by maintaining runtime pointer invariants (for example, that globals and the heap may not generally point into a stack).

Types

type ArrayType added in v0.0.32

type ArrayType struct {
	Type
	Elem  *Type   // array element type
	Slice *Type   // slice type
	Len   uintptr // array length
}

ArrayType represents an array type.

func (*ArrayType) Element added in v0.0.32

func (t *ArrayType) Element() *Type

Elem returns the element type of the array

func (*ArrayType) Length added in v0.0.32

func (t *ArrayType) Length() int

Length returns the length of the array

type EmptyInterface added in v0.0.13

type EmptyInterface struct {
	Type *Type
	Data unsafe.Pointer
}

EmptyInterface describes the layout of a "interface{}" or a "any."

type Name added in v0.0.13

type Name struct {
	Bytes *byte
}

func (Name) DataChecked added in v0.0.13

func (n Name) DataChecked(off int, whySafe string) *byte

DataChecked does pointer arithmetic on n's Bytes, and that arithmetic is asserted to be safe for the reason in whySafe (which can appear in a backtrace, etc.)

func (Name) HasTag added in v0.0.13

func (n Name) HasTag() bool

HasTag returns true iff there is tag data following this name

func (Name) IsEmbedded added in v0.0.13

func (n Name) IsEmbedded() bool

IsEmbedded returns true iff n is embedded (an anonymous field).

func (Name) IsExported added in v0.0.13

func (n Name) IsExported() bool

IsExported reports whether the name is exported.

func (Name) Name added in v0.0.13

func (n Name) Name() string

Name returns the tag string for n, or empty if there is none.

func (Name) ReadVarint added in v0.0.13

func (n Name) ReadVarint(off int) (int, int)

ReadVarint parses a varint as encoded by encoding/binary. It returns the number of encoded bytes and the encoded value.

func (Name) String added in v0.0.13

func (n Name) String() string

String returns the name as a string.

func (Name) Tag added in v0.0.13

func (n Name) Tag() string

Tag returns the tag string for n, or empty if there is none.

type NameOff added in v0.0.13

type NameOff int32

NameOff is the Offset to a Name from moduledata.types. See resolveNameOff in runtime.

type PtrType added in v0.0.17

type PtrType struct {
	Type
	Elem *Type // pointer element type
}

PtrType represents a pointer type.

type SliceType added in v0.0.32

type SliceType struct {
	Type
	Elem *Type // slice element type
}

SliceType represents a slice type.

func (*SliceType) Element added in v0.0.32

func (t *SliceType) Element() *Type

Elem returns the element type of the slice

type StructField added in v0.0.13

type StructField struct {
	Name Name    // name is always non-empty
	Typ  *Type   // type of field
	Off  uintptr // offset within struct, in bytes
}

A StructField describes a single field in a struct.

func (*StructField) Embedded added in v0.0.13

func (f *StructField) Embedded() bool

func (StructField) Tag added in v0.0.13

func (f StructField) Tag() StructTag

Tag returns the field's tag as a StructTag.

type StructTag added in v0.0.13

type StructTag string

StructTag is the tag string in a struct field (similar to reflect.StructTag)

func (StructTag) Get added in v0.0.13

func (tag StructTag) Get(key string) string

Get returns the value associated with key in the tag string. If there is no such key in the tag, Get returns the empty string.

type StructType added in v0.0.13

type StructType struct {
	Type
	PkgPath Name
	Fields  []StructField
}

type TFlag added in v0.0.13

type TFlag uint8

TFlag is used by a Type to signal what extra type information is available in the memory directly following the Type value.

type Type added in v0.0.13

type Type struct {
	Size        uintptr
	PtrBytes    uintptr // number of (prefix) bytes in the type that can contain pointers
	Hash        uint32  // Hash of type; avoids computation in Hash tables
	TFlag       TFlag   // extra type information flags
	Align_      uint8   // alignment of variable with this type
	FieldAlign_ uint8   // alignment of struct field with this type
	Kind_       Kind    // enumeration for C
	// function for comparing objects of this type
	Equal func(unsafe.Pointer, unsafe.Pointer) bool
	// GCData stores the GC type data for the garbage collector.
	// Normally, GCData points to a bitmask that describes the
	// ptr/nonptr Fields of the type. The bitmask will have at
	// least PtrBytes/ptrSize bits.
	// If the TFlagGCMaskOnDemand bit is set, GCData is instead a
	// **byte and the pointer to the bitmask is one dereference away.
	// The runtime will build the bitmask if needed.
	// (See runtime/type.go:getGCMask.)
	// Note: multiple types may have the same value of GCData,
	// including when TFlagGCMaskOnDemand is set. The types will, of course,
	// have the same pointer layout (but not necessarily the same size).
	GCData    *byte
	Str       NameOff // string form
	PtrToThis TypeOff // type for pointer to this type, may be zero
}

func TypeOf added in v0.0.13

func TypeOf(i any) *Type

TypeOf returns the reflection Type that represents the dynamic type of i. If i is a nil interface value, TypeOf returns nil.

func (*Type) ArrayType added in v0.0.32

func (t *Type) ArrayType() *ArrayType

ArrayType returns t cast to a *ArrayType, or nil if its tag does not match.

func (*Type) Elem added in v0.0.32

func (t *Type) Elem() *Type

Elem returns the element type for t if t is an array, channel, map, pointer, or slice, otherwise nil.

func (*Type) Field added in v0.0.13

func (t *Type) Field(i int) (StructField, error)

Field returns the i'th field of the struct type. It returns an error if the type is not a struct or the index is out of range.

func (*Type) IfaceIndir added in v0.0.13

func (t *Type) IfaceIndir() bool

IfaceIndir reports whether t is stored indirectly in an interface value.

func (*Type) Kind added in v0.0.13

func (t *Type) Kind() Kind

func (*Type) Name added in v0.0.16

func (t *Type) Name() string

Name returns the type's name within its package for a defined type. For TinyGo compatibility, struct names are resolved using the StructDictionary

func (*Type) NameByIndex added in v0.0.19

func (t *Type) NameByIndex(i int) (string, error)

Name returns the name of a struct type's i'th field. It panics if the type's Kind is not Struct. It panics if i is out of range.

func (*Type) NumField added in v0.0.13

func (t *Type) NumField() (int, error)

NumField returns the number of fields in the struct type. It returns an error if the type is not a struct.

func (*Type) PtrType added in v0.0.32

func (t *Type) PtrType() *PtrType

PtrType returns t cast to a *PtrType, or nil if its tag does not match.

func (*Type) SliceType added in v0.0.32

func (t *Type) SliceType() *SliceType

SliceType returns t cast to a *SliceType, or nil if its tag does not match.

func (*Type) String added in v0.0.13

func (t *Type) String() string

func (*Type) StructID added in v0.0.16

func (t *Type) StructID() uint32

StructID returns a unique identifier for struct types based on runtime hash Returns 0 for non-struct types

func (*Type) StructType added in v0.0.13

func (t *Type) StructType() *StructType

StructType returns t cast to a *StructType, or nil if its tag does not match.

type TypeOff added in v0.0.13

type TypeOff int32

TypeOff is the Offset to a type from moduledata.types. See resolveTypeOff in runtime.

type Value added in v0.0.13

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

func Indirect added in v0.0.32

func Indirect(v Value) Value

Indirect returns the value that v points to. If v is a nil pointer, Indirect returns a zero Value. If v is not a pointer, Indirect returns v.

func MakeSlice added in v0.0.32

func MakeSlice(typ *Type, len, cap int) (Value, error)

MakeSlice creates a new zero-initialized slice value for the specified slice type, length, and capacity. Implementation adapted from /usr/local/go/src/reflect/value.go:2904

func New

func New(typ *Type) Value

New returns a Value representing a pointer to a new zero value for the specified type. That is, the returned Value's Type is PtrTo(typ).

func ValueOf added in v0.0.13

func ValueOf(i any) Value

ValueOf returns a new Value initialized to the concrete value stored in the interface i. ValueOf(nil) returns the zero Value.

func Zero added in v0.0.32

func Zero(typ *Type) Value

Zero returns a Value representing the zero value for the specified type.

func (Value) Addr added in v0.0.32

func (v Value) Addr() (Value, error)

Addr returns a pointer value representing the address of v. It returns an error if CanAddr would return false.

func (Value) Bool added in v0.0.32

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

Bool returns v's underlying value. It returns an error if v's Kind is not Bool.

func (Value) CanAddr added in v0.0.32

func (v Value) CanAddr() bool

CanAddr reports whether the value's address can be obtained with Value.Addr. Such values are called addressable. A value is addressable if it is an element of a slice, an element of an addressable array, a field of an addressable struct, or the result of dereferencing a pointer. If CanAddr returns false, calling Value.Addr will panic.

func (Value) Cap added in v0.0.32

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

Cap returns v's capacity. It returns an error if v's Kind is not Array, Chan, Slice or pointer to Array.

func (Value) Elem added in v0.0.17

func (v Value) Elem() (Value, error)

Elem returns the value that the pointer v points to. It panics if v's Kind is not Ptr. It returns the zero Value if v is a nil pointer.

func (Value) Field added in v0.0.13

func (v Value) Field(i int) (Value, error)

Field returns the i'th field of the struct v. Returns an error if v is not a struct or i is out of range.

func (Value) Float added in v0.0.32

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

Float returns v's underlying value, as a float64. It returns an error if v's Kind is not Float32 or Float64.

func (Value) Index added in v0.0.32

func (v Value) Index(i int) (Value, error)

Index returns v's i'th element. It returns an error if v's Kind is not Array, Slice, or String or i is out of range.

func (Value) Int added in v0.0.32

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

Int returns v's underlying value, as an int64. It returns an error if v's Kind is not Int, Int8, Int16, Int32, or Int64.

func (Value) Interface added in v0.0.19

func (v Value) Interface() (i any, err error)

Interface returns v's current value as an interface{}. It is equivalent to:

var i interface{} = (v's underlying value)

For a Value created from a nil interface value, Interface returns nil.

func (Value) IsNil added in v0.0.32

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

IsNil reports whether its argument v is nil. It returns an error if v's Kind is not Chan, Func, Interface, Map, Pointer, or Slice.

func (Value) Kind added in v0.0.32

func (v Value) Kind() Kind

Kind returns the specific kind of this value.

func (Value) Len added in v0.0.32

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

Len returns v's length. It returns an error if v's Kind is not Array, Chan, Map, Slice, or String.

func (Value) NumField added in v0.0.13

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

func (Value) Set added in v0.0.32

func (v Value) Set(x Value) error

Set assigns x to the value v. It returns an error if CanSet would return false.

func (Value) SetBool added in v0.0.32

func (v Value) SetBool(x bool) error

SetBool sets the bool value to the field represented by Value.

func (Value) SetBytes added in v0.0.32

func (v Value) SetBytes(x []byte) error

SetBytes sets the byte slice value to the field represented by Value.

func (Value) SetFloat added in v0.0.32

func (v Value) SetFloat(x float64) error

SetFloat sets the float value to the field represented by Value.

func (Value) SetInt added in v0.0.32

func (v Value) SetInt(x int64) error

SetInt sets the int value to the field represented by Value.

func (Value) SetString added in v0.0.17

func (v Value) SetString(x string) error

SetString sets the string value to the field represented by Value. It uses unsafe to write the value to the memory location of the field.

func (Value) SetUint added in v0.0.32

func (v Value) SetUint(x uint64) error

SetUint sets the uint value to the field represented by Value.

func (Value) String added in v0.0.32

func (v Value) String() string

String returns the string v's underlying value, as a string. String is a special case because of Go's String method convention. Unlike the other getters, it does not panic if v's Kind is not String. Instead, it returns a string of the form "<Translate value>" where Translate is v's type.

func (Value) Type added in v0.0.19

func (v Value) Type() *Type

Type returns v's type.

func (Value) Uint added in v0.0.32

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

Uint returns v's underlying value, as a uint64. It returns an error if v's Kind is not Uint, Uint8, Uint16, Uint32, or Uint64.

Jump to

Keyboard shortcuts

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