module walker import toml.ast // Visitor defines a visit method which is invoked by the walker on each Value node it encounters. pub interface Visitor { visit(value &ast.Value) ! } // Modifier defines a modify method which is invoked by the walker on each Value node it encounters. pub interface Modifier { modify(mut value ast.Value) ! } pub type InspectorFn = fn (value &ast.Value, data voidptr) ! struct Inspector { inspector_callback InspectorFn = unsafe { nil } mut: data voidptr } // visit calls the inspector callback on the specified Value node. pub fn (i &Inspector) visit(value &ast.Value) ! { i.inspector_callback(value, i.data) or { return err } } // inspect traverses and checks the AST Value node on a depth-first order and based on the data given pub fn inspect(value &ast.Value, data voidptr, inspector_callback InspectorFn) ! { walk(Inspector{inspector_callback, data}, value)! } // walk traverses the AST using the given visitor pub fn walk(visitor Visitor, value &ast.Value) ! { if value is map[string]ast.Value { value_map := value as map[string]ast.Value for _, val in value_map { walk(visitor, &val)! } } if value is []ast.Value { value_array := value as []ast.Value for val in value_array { walk(visitor, &val)! } } else { visitor.visit(value)! } } // walk_and_modify traverses the AST using the given modifier and lets the visitor // modify the contents. pub fn walk_and_modify(modifier Modifier, mut value ast.Value) ! { if value is map[string]ast.Value { mut value_map := value as map[string]ast.Value for _, mut val in value_map { walk_and_modify(modifier, mut &val)! } } if value is []ast.Value { mut value_array := value as []ast.Value for mut val in value_array { walk_and_modify(modifier, mut &val)! } } else { modifier.modify(mut value)! } }