go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

resource.go (5226B)


      1 package resource
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 )
      7 
      8 
      9 // Result contains the results of an external code operation.
     10 type Result struct {
     11 	// content value for symbol after execution.
     12 	Content string
     13 	// application defined status code which can complement error returns
     14 	Status int
     15 	// request caller to set error flags at given indices.
     16 	FlagSet []uint32
     17 	// request caller to reset error flags at given indices.
     18 	FlagReset []uint32
     19 }
     20 
     21 // EntryFunc is a function signature for a function that resolves the symbol of a LOAD instruction.
     22 //
     23 // The EntryFunc receives the current input buffer from the client, aswell as the symbol of the current state node being executed.
     24 //
     25 // The implementer MUST NOT modify state flags or cache inside the function. The resource.Result object MUST be used instead.
     26 type EntryFunc func(ctx context.Context, nodeSym string, input []byte) (Result, error)
     27 // CodeFunc is the function signature for retrieving bytecode for a given symbol.
     28 type CodeFunc func(ctx context.Context, nodeSym string) ([]byte, error)
     29 // MenuFunc is the function signature for retrieving menu symbol resolution.
     30 type MenuFunc func(ctx context.Context, menuSym string) (string, error)
     31 // TemplateFunc is the function signature for retrieving a render template for a given symbol.
     32 type TemplateFunc func(ctx context.Context, nodeSym string) (string, error)
     33 // FuncForFunc is a function that returns an EntryFunc associated with a LOAD instruction symbol.
     34 type FuncForFunc func(ctx context.Context, loadSym string) (EntryFunc, error)
     35 
     36 // Resource implementation are responsible for retrieving values and templates for symbols, and can render templates from value dictionaries.
     37 //
     38 // All methods must fail if the symbol cannot be resolved.
     39 type Resource interface {
     40 	// GetTemplate retrieves a render template associated with the given symbol.
     41 	GetTemplate(ctx context.Context, nodeSym string) (string, error)
     42 	// GetCode retrieves the bytecode associated with the given symbol.
     43 	GetCode(ctx context.Context, nodeSym string) ([]byte, error)
     44 	// GetMenu retrieves the menu label associated with the given symbol.
     45 	GetMenu(ctx context.Context, menuSym string) (string, error)
     46 	// FuncFor retrieves the external function (EntryFunc) associated with the given symbol.
     47 	FuncFor(ctx context.Context, loadSym string) (EntryFunc, error)
     48 	// Close implements the io.Closer interface.
     49 	//
     50 	// Safely shuts down retrieval backend.
     51 	Close() error
     52 }
     53 
     54 // MenuResource contains the base definition for building Resource implementations.
     55 type MenuResource struct {
     56 	sinkValues []string
     57 	codeFunc CodeFunc
     58 	templateFunc TemplateFunc
     59 	menuFunc MenuFunc
     60 	funcFunc FuncForFunc
     61 	fns map[string]EntryFunc
     62 }
     63 
     64 var (
     65 	noBinFunc = func(ctx context.Context, s string) ([]byte, error) {
     66 		logg.WarnCtxf(ctx, "no resource getter set!", "s", s)
     67 		return []byte{}, nil
     68 	}
     69 	noStrFunc = func(ctx context.Context, s string) (string, error) {
     70 		logg.WarnCtxf(ctx, "no resource getter set!", "s", s)
     71 		return "", nil
     72 	}
     73 )
     74 
     75 // NewMenuResource creates a new MenuResource instance.
     76 func NewMenuResource() *MenuResource {
     77 	rs := &MenuResource{}
     78 	rs.funcFunc = rs.FallbackFunc
     79 	rs.codeFunc = noBinFunc
     80 	rs.templateFunc = noStrFunc
     81 	rs.menuFunc = noStrFunc
     82 	return rs
     83 }
     84 
     85 // WithCodeGetter sets the code symbol resolver method.
     86 func(m *MenuResource) WithCodeGetter(codeGetter CodeFunc) *MenuResource {
     87 	m.codeFunc = codeGetter
     88 	return m
     89 }
     90 
     91 // WithEntryGetter sets the content symbol resolver getter method.
     92 func(m *MenuResource) WithEntryFuncGetter(entryFuncGetter FuncForFunc) *MenuResource {
     93 	m.funcFunc = entryFuncGetter
     94 	return m
     95 }
     96 
     97 // WithTemplateGetter sets the template symbol resolver method.
     98 func(m *MenuResource) WithTemplateGetter(templateGetter TemplateFunc) *MenuResource {
     99 	m.templateFunc = templateGetter
    100 	return m
    101 }
    102 
    103 // WithMenuGetter sets the menu symbol resolver method.
    104 func(m *MenuResource) WithMenuGetter(menuGetter MenuFunc) *MenuResource {
    105 	m.menuFunc = menuGetter
    106 	return m
    107 }
    108 
    109 // FuncFor implements Resource interface.
    110 func(m *MenuResource) FuncFor(ctx context.Context, sym string) (EntryFunc, error) {
    111 	return m.funcFunc(ctx, sym)
    112 }
    113 
    114 // GetCode implements Resource interface.
    115 func(m *MenuResource) GetCode(ctx context.Context, sym string) ([]byte, error) {
    116 	return m.codeFunc(ctx, sym)
    117 }
    118 
    119 // GetTemplate implements Resource interface.
    120 func(m *MenuResource) GetTemplate(ctx context.Context, sym string) (string, error) {
    121 	return m.templateFunc(ctx, sym)
    122 }
    123 
    124 // GetMenu implements Resource interface.
    125 func(m *MenuResource) GetMenu(ctx context.Context, sym string) (string, error) {
    126 	return m.menuFunc(ctx, sym)
    127 }
    128 
    129 // AddLocalFunc associates a handler function with a external function symbol to be returned by FallbackFunc.
    130 func(m *MenuResource) AddLocalFunc(sym string, fn EntryFunc) {
    131 	if m.fns == nil {
    132 		m.fns = make(map[string]EntryFunc)
    133 	}
    134 	m.fns[sym] = fn
    135 }
    136 
    137 // FallbackFunc returns the default handler function for a given external function symbol.
    138 func(m *MenuResource) FallbackFunc(ctx context.Context, sym string) (EntryFunc, error) {
    139 	fn, ok := m.fns[sym]
    140 	if !ok {
    141 		return nil, fmt.Errorf("unknown function: %s", sym)
    142 	}
    143 	return fn, nil
    144 }
    145 
    146 // Close implements the Resource interface.
    147 func(m *MenuResource) Close() error {
    148 	return nil
    149 }