go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/pkg/incrutil/node_helpers.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package incrutil 9 10 import ( 11 "fmt" 12 13 "github.com/wcharczuk/go-incr" 14 "go.charczuk.com/projects/nodes/pkg/types" 15 ) 16 17 // LinkNodes adds inputs to a given child, associating the two nodes in the graph. 18 func LinkNodes(child incr.INode, inputs ...incr.INode) error { 19 for _, input := range inputs { 20 if err := incr.ExpertGraph(incr.GraphForNode(child)).AddChild(child, input); err != nil { 21 return err 22 } 23 } 24 return nil 25 } 26 27 // Unlink nodes removes the metadata association between two nodes 28 // but does _not_ remove node type specific input tracking. 29 func UnlinkNodes(child incr.INode, inputs ...incr.INode) { 30 for _, input := range inputs { 31 incr.ExpertGraph(incr.GraphForNode(child)).RemoveParent(child, input) 32 } 33 } 34 35 // LabelOrID returns either the node's label or it's short id. 36 func LabelOrID(n incr.INode) string { 37 if n.Node().Label() != "" { 38 return n.Node().Label() 39 } 40 return n.Node().ID().Short() 41 } 42 43 // SetNodeValueOnline calls set on a given node with the appropriate type. 44 // 45 // If the node is a var node, it will be marked as stale. 46 func SetNodeValueOnline(n incr.INode, value any) error { 47 if typed, ok := n.(VarIncr[*types.Table]); ok { 48 if valueTyped, ok := value.(*types.Table); ok { 49 typed.Set(valueTyped) 50 return nil 51 } 52 if valueTyped, ok := value.(map[string]any); ok { 53 parsedTable, err := types.TableFromJSON(valueTyped) 54 if err != nil { 55 return err 56 } 57 typed.Set(parsedTable) 58 return nil 59 } 60 return fmt.Errorf("invalid var type to set value for: %T", value) 61 } 62 if typed, ok := n.(VarIncr[types.SVG]); ok { 63 if valueTyped, ok := value.(types.SVG); ok { 64 typed.Set(valueTyped) 65 return nil 66 } 67 if valueTyped, ok := value.(map[string]any); ok { 68 parsedSVG, err := types.SVGFromJSON(valueTyped) 69 if err != nil { 70 return err 71 } 72 typed.Set(*parsedSVG) 73 return nil 74 } 75 return fmt.Errorf("invalid var type to set value for: %T", value) 76 } 77 if typed, ok := n.(ISetRawValue); ok { 78 return typed.SetRawValue(value) 79 } 80 return nil 81 } 82 83 // SetNodeValueDuringDeserialization sets the underlying value for the node 84 // but does _not_ mark the node as stale if it's a var! 85 func SetNodeValueDuringDeserialization(n incr.INode, value any) error { 86 var typedValue any 87 switch GetNodeValue(n).(type) { 88 case *types.Table: 89 if valueTyped, ok := value.(*types.Table); ok { 90 typedValue = valueTyped 91 } else if valueTyped, ok := value.(map[string]any); ok { 92 parsedTable, err := types.TableFromJSON(valueTyped) 93 if err != nil { 94 return err 95 } 96 typedValue = parsedTable 97 } 98 case types.SVG: 99 if valueTyped, ok := value.(types.SVG); ok { 100 typedValue = valueTyped 101 } else if valueTyped, ok := value.(map[string]any); ok { 102 parsedSVG, err := types.SVGFromJSON(valueTyped) 103 if err != nil { 104 return err 105 } 106 typedValue = *parsedSVG 107 } 108 default: 109 typedValue = value 110 } 111 if typed, ok := n.(ISetRawVarValue); ok { 112 return typed.SetRawVarValue(typedValue) 113 } 114 if typed, ok := n.(ISetRawValue); ok { 115 return typed.SetRawValue(typedValue) 116 } 117 return nil 118 } 119 120 // GetNodeValue gets the raw value of a node. 121 func GetNodeValue(n incr.INode) any { 122 switch typed := n.(type) { 123 case IRawValue: 124 return typed.RawValue() 125 default: 126 return nil 127 } 128 } 129 130 // ApplyNodeTableOps applies node table operations. 131 // 132 // This is only valid for incr types of table. 133 func ApplyNodeTableOps(g *incr.Graph, n incr.INode, ops ...types.TableOp) error { 134 switch typed := n.(type) { 135 case VarIncr[*types.Table]: 136 if err := typed.Value().ApplyOps(ops...); err != nil { 137 return err 138 } 139 g.SetStale(n) 140 return nil 141 default: 142 return fmt.Errorf("invalid node value type for table ops apply: %T", typed) 143 } 144 }