package flowserver import ( "encoding/json" "flow" "flow/registry" "log" "reflect" ) // Node that will contain registry src type Node struct { ID string `json:"id"` Src string `json:"src"` Label string `json:"label"` Prop map[string]string `json:"prop"` } // Link that joins two nodes type Link struct { From string `json:"from"` To string `json:"to"` In int `json:"in"` } // FlowDocument flow document type FlowDocument struct { Nodes []Node `json:"nodes"` Links []Link `json:"links"` } // FlowBuild build a flowGraph func FlowBuild(rawData []byte, r *registry.R) (*flow.Flow, error) { doc := FlowDocument{[]Node{}, []Link{}} err := json.Unmarshal(rawData, &doc) if err != nil { return nil, err } f := flow.New() f.SetRegistry(r) nodeMap := map[string]Node{} for _, n := range doc.Nodes { nodeMap[n.ID] = n } inputMap := map[string]flow.Operation{} ninput := 0 for _, n := range doc.Nodes { if n.Src == "Input" || n.Src == "Variable" || n.Src == "Const" { continue } // Find link refered as To entry, err := r.Entry(n.Src) if err != nil { return nil, err } param := make([]flow.Data, len(entry.Inputs)) // Find links for _, l := range doc.Links { if l.To != n.ID { continue } // Define operators here from := nodeMap[l.From] switch from.Src { case "Input": inOp, ok := inputMap[n.ID] if !ok { inOp = f.In(ninput) inputMap[n.ID] = inOp ninput++ } param[l.In] = inOp // By id perhaps case "Variable": param[l.In] = f.Var(from.ID, from.Prop["init"]) case "Const": // XXX: Automate this in a func newVal := reflect.New(entry.Inputs[l.In]) raw := from.Label //raw := from.Prop["value"] if _, ok := newVal.Interface().(*string); ok { log.Println("Trying to unmarshal a string") raw = "\"" + raw + "\"" } log.Println("Will unmarshal raw:", raw) err := json.Unmarshal([]byte(raw), newVal.Interface()) if err != nil { // ignore error log.Println("unmarshalling Error", err) //param[l.In] = nil //continue } param[l.In] = f.Const(newVal.Elem().Interface()) default: param[l.In] = f.Res(from.ID) } } f.DefOp(n.ID, n.Src, param...) } return f, nil }