User Tools

Site Tools


Simple object constructor

This is examples of re-construct object from object description.

with embedded JS virtial machine

picker-js.go
/*
 * Copyright: Oleg Borodin <onborodin@gmail.com>
 */
 
package main
 
import (
    "encoding/json"
    "fmt"
 
    "github.com/dop251/goja"
)
 
const (
    marhallIndent1  string = ""
    marhallIndent2  string = "   "
)
 
func main() {
    // make & export json engine description
    engineDesc := makeEngineDesc()
    fmt.Println("export descrition:", string(engineDesc))
 
    // construct engine from imported description
    engine := constructEngine(engineDesc)
 
    // run constructed engine 
    runEngine(engine)
}
 
func makeEngineDesc() []byte {
    engine := Engine{
        Name:   "engine#1",
        Id:     "37955138-964a-40f5-a4e2-4f50d6c06286",
        Run:   makeRunFuncA(),
    }
    jsonBytes, _ := json.MarshalIndent(engine, marhallIndent1, marhallIndent2)
    return jsonBytes
}
 
func constructEngine(desc []byte) *Engine {
    // create empty engine
    engine := &Engine{}
    // fill engine data from desription 
    _ = json.Unmarshal(desc, engine) 
    return engine
}
 
func runEngine(engine *Engine) {
    fmt.Println("run engine", engine.Name)
 
    vm := goja.New()
    vmResult, _:= vm.RunString(engine.Run.Func) 
    result, _:= vmResult.Export().(string)
    fmt.Println(result)
}
 
type Engine struct {
    Name    string          `json:"name"`
    Id      string          `json:"id"`
    Run     *RunFunc        `json:"runFunc"`
}
 
type RunFunc struct {
    Name    string          `json:"name"`
    Id      string          `json:"id"`
    Args    []Arg           `json:"args"`
    Func    string          `json:"func"` 
}
 
type Arg struct {
    Type    ArgType         `json:"argType"`
    Name    string          `json:"name"`
}
 
type ArgType = string
 
func makeRunFuncA() *RunFunc {
    runFunc := &RunFunc{
        Name:       "runFunc#1",
        Id:         "81613ac6-e247-4a31-b6f8-05dec6877d95",
        Args:       make([]Arg, 0),
        Func:       `function hello() { return "hello world #1" }; hello();`,
    }
    return runFunc
}
 
func makeRunFuncB() *RunFunc {
    runFunc := &RunFunc{
        Name:       "runFunc#2",
        Id:         "378739bd-792e-45f7-b8dc-6bab48856e23",
        Args:       make([]Arg, 0),
        Func:       `function hello() { return "hello world #2" }; hello();`,
    }
    return runFunc
}
//EOF

Out #1

$ go run main2.go
export descrition: 
{
   "name": "engine#1",
   "id": "37955138-964a-40f5-a4e2-4f50d6c06286",
   "runFunc": {
      "name": "runFunc#1",
      "id": "81613ac6-e247-4a31-b6f8-05dec6877d95",
      "args": [],
      "func": "function hello() { return \"hello world #1\" }; hello();"
   }
}
run engine engine#1
hello world #1

with included function collection end resolver

picker.go
/*
 * Copyright: Oleg Borodin <onborodin@gmail.com>
 */
 
package main
 
import (
    "encoding/json"
    "fmt"
)
 
const (
    marhallIndent1  string = ""
    marhallIndent2  string = "   "
)
 
func main() {
    // make & export json engine description
    engineDesc := makeEngineDesc()
    fmt.Println("engine desription:")
    fmt.Println(string(engineDesc))
 
    // construct engine from imported description
    engine := constructEngine(engineDesc)
 
    // run constructed engine 
    runEngine(engine)
}
 
func makeEngineDesc() []byte {
    engine := Engine{
        Name:   "engine#1",
        Id:     "37955138-964a-40f5-a4e2-4f50d6c06286",
        Run:   makeRunFuncA(),
    }
    jsonBytes, _ := json.MarshalIndent(engine, marhallIndent1, marhallIndent2)
    return jsonBytes
}
 
func constructEngine(desc []byte) *Engine {
    // create empty engine
    engine := &Engine{}
 
    // fill engine data from desription 
    _ = json.Unmarshal(desc, engine) 
 
    // make function collection
    funcCollect := makeFuncCollection()
 
    // connect real function 
    engine.Run.Func = findFuncCollection(funcCollect, engine.Run.Id)
    return engine
}
 
func runEngine(engine *Engine) {
    fmt.Println("run engine", engine.Name)
    engine.Run.Func()
}
 
type FuncCollect = []*RunFunc
 
func makeFuncCollection() FuncCollect {
    collect := make([]*RunFunc, 0)
    collect = append(collect, makeRunFuncA())
    return collect
}
func findFuncCollection(collect FuncCollect, id string) RunFuncBody {
    for i := range collect {
        if collect[i].Id == id {
            return collect[i].Func
        }
    }
    return RunFuncDummy
}
 
type Engine struct {
    Name    string          `json:"name"`
    Id      string          `json:"id"`
    Run     *RunFunc        `json:"runFunc"`
}
 
type RunFunc struct {
    Name    string          `json:"name"`
    Id      string          `json:"id"`
    Args    []Arg           `json:"args"`
    Func    RunFuncBody     `json:"-"` 
}
 
type Arg struct {
    Type    ArgType         `json:"argType"`
    Name    string          `json:"name"`
}
 
type ArgType = string
type RunFuncBody = func() 
 
func makeRunFuncA() *RunFunc {
    runFunc := &RunFunc{
        Name:       "runFunc#1",
        Id:         "81613ac6-e247-4a31-b6f8-05dec6877d95",
        Args:       make([]Arg, 0),
        Func:       RunFuncA,
    }
    return runFunc
}
 
func RunFuncA() {
    fmt.Println("hello world #1")
}
 
func makeRunFuncB() *RunFunc {
    runFunc := &RunFunc{
        Name:       "runFunc#2",
        Id:         "378739bd-792e-45f7-b8dc-6bab48856e23",
        Args:       make([]Arg, 0),
        Func:       RunFuncB,
    }
    return runFunc
}
 
func RunFuncB() {
    fmt.Println("hello world #2")
}
 
func RunFuncDummy() {
    fmt.Println("hello dummy")
}
//EOF

Out #2

$ go run main.go
engine desription:
{
   "name": "engine#1",
   "id": "37955138-964a-40f5-a4e2-4f50d6c06286",
   "runFunc": {
      "name": "runFunc#1",
      "id": "81613ac6-e247-4a31-b6f8-05dec6877d95",
      "args": []
   }
}
run engine engine#1
hello world #1