go-vise

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

resource.go (5251B)


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