Skip to content

Instantly share code, notes, and snippets.

View jonbodner's full-sized avatar

Jon Bodner jonbodner

  • @jonbodner@noc.social
View GitHub Profile
type outExp struct {
out []reflect.Value
expiry time.Time
}
func Cacher(f interface{}, expiration time.Duration) (interface{}, error) {
ft := reflect.TypeOf(f)
if ft.Kind() != reflect.Func {
return nil, errors.New("Only for functions")
}
func buildInStruct(ft reflect.Type) (reflect.Type, error) {
if ft.NumIn() == 0 {
return nil, errors.New("Must have at least one param")
}
var sf []reflect.StructField
for i := 0; i < ft.NumIn(); i++ {
ct := ft.In(i)
if !ct.Comparable() {
return nil, fmt.Errorf("parameter %d of type %s and kind %v is not comparable", i+1, ct.Name(), ct.Kind())
}
func Cacher(f interface{}, expiration time.Duration) (interface{}, error) {
ft := reflect.TypeOf(f)
if ft.Kind() != reflect.Func {
return nil, errors.New("Only for functions")
}
return f, nil
}
// Takes in a function and a time.Duration and returns a caching version of the function
//
// The limitations on memoization are:
//
// — there must be at least one in parameter
//
// — there must be at least one out parameter
//
// — the in parameters must be comparable. That means they cannot be of kind slice, map, or func,
// nor can input parameters be structs that contain (at any level) slices, maps, or funcs.
subv = v
destring = f.quoted
for _, i := range f.index {
if subv.Kind() == reflect.Ptr {
if subv.IsNil() {
subv.Set(reflect.New(subv.Type().Elem()))
}
subv = subv.Elem()
}
subv = subv.Field(i)
// Decoding into nil interface? Switch to non-reflect code.
if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
v.Set(reflect.ValueOf(d.objectInterface()))
return
}
func (d *decodeState) unmarshal(v interface{}) (err error) {
<skip over some setup>
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Ptr || rv.IsNil() {
return &InvalidUnmarshalError{reflect.TypeOf(v)}
}
d.scan.reset()
// We decode rv not rv.Elem because the Unmarshaler interface
// test must be applied at the top level of the value.
d.value(rv)
type Foo struct {
A int
}
func (f Foo) Double() int {
return f.A * 2
}
type Bar struct {
Foo
func MakeStruct(vals ...interface{}) interface{} {
var sfs []reflect.StructField
for k, v := range vals {
t := reflect.TypeOf(v)
sf := reflect.StructField{
Name: fmt.Sprintf("F%d", (k + 1)),
Type: t,
}
sfs = append(sfs, sf)
}
func MakeTimedFunction(f interface{}) interface{} {
rf := reflect.TypeOf(f)
if rf.Kind() != reflect.Func {
panic("expects a function")
}
vf := reflect.ValueOf(f)
wrapperF := reflect.MakeFunc(rf, func(in []reflect.Value) []reflect.Value {
start := time.Now()
out := vf.Call(in)
end := time.Now()