@@ -11,14 +11,23 @@ var (
1111
1212// JSONLogic is an evaluator of json logic with a set of operations.
1313type JSONLogic struct {
14- ops map [string ]Operation
14+ parent * JSONLogic
15+ ops map [string ]Operation
1516}
1617
1718type Applier func (logic , data interface {}) (res interface {}, err error )
1819
1920type Operation func (apply Applier , params []interface {}, data interface {}) (interface {}, error )
2021
21- // New creates a JSONLogic with standard operations.
22+ // NewInherit creates a child JSONLogic instance.
23+ func NewInherit (parent * JSONLogic ) * JSONLogic {
24+ return & JSONLogic {
25+ parent : parent ,
26+ ops : make (map [string ]Operation ),
27+ }
28+ }
29+
30+ // New creates a root (no parent) JSONLogic with standard operations.
2231func New () * JSONLogic {
2332 ret := NewEmpty ()
2433 // Data access.
@@ -59,6 +68,7 @@ func New() *JSONLogic {
5968 return ret
6069}
6170
71+ // NewEmpty creates a root (no parent) JSONLogic with no operation.
6272func NewEmpty () * JSONLogic {
6373 return & JSONLogic {
6474 ops : make (map [string ]Operation ),
@@ -112,7 +122,14 @@ func (jl *JSONLogic) Apply(logic, data interface{}) (res interface{}, err error)
112122 }
113123 }()
114124
115- opFn := jl .ops [op ]
125+ var opFn Operation
126+ for inst := jl ; inst != nil ; inst = inst .parent {
127+ var ok bool
128+ opFn , ok = inst .ops [op ]
129+ if ok {
130+ break
131+ }
132+ }
116133 if opFn == nil {
117134 return nil , fmt .Errorf ("Apply: operator %q not found" , op )
118135 }
@@ -126,6 +143,7 @@ func AddOperation(name string, op Operation) {
126143}
127144
128145// AddOperation adds a named operation to JSONLogic instance.
146+ // Can override parent's same name operation.
129147func (jl * JSONLogic ) AddOperation (name string , op Operation ) {
130148 jl .ops [name ] = op
131149}
@@ -138,7 +156,8 @@ func Clone() *JSONLogic {
138156// Clone clones a JSONLogic instance.
139157func (jl * JSONLogic ) Clone () * JSONLogic {
140158 ret := & JSONLogic {
141- ops : make (map [string ]Operation ),
159+ parent : jl .parent ,
160+ ops : make (map [string ]Operation ),
142161 }
143162 for k , v := range jl .ops {
144163 ret .ops [k ] = v
0 commit comments