basic usage
PathTree!string tree = new ConcretePathTree!string; tree.put("abc.def.g", "x"); tree.put("abc.def.g", "y"); assert(tree.get("abc.def.g") == "y".some); assert(tree.getVersion("abc.def.g") == 1.some); assert(tree.get("abc.def.g.h") == no!string); assert(tree.getVersion("abc.def.g.h") == no!size_t); assert(tree.resolve("abc.def.g.h") == "y".some); assert(tree.resolveVersion("abc.def.g.h") == 1.some); assert(tree.resolveCoordinates("abc.def.g.h") == "abc.def.g".some); auto mappedPaths = tree.subtree("abc"); assert(mappedPaths.get("def.g") == "y".some); assert(mappedPaths.getVersion("def.g") == 1.some); assert(mappedPaths.resolve("def.g.h") == "y".some); assert(mappedPaths.resolveVersion("def.g.h") == 1.some); mappedPaths = mappedPaths.subtree("def"); assert(mappedPaths.get("g") == "y".some); assert(mappedPaths.getVersion("g") == 1.some); assert(mappedPaths.resolve("g.h") == "y".some); assert(mappedPaths.resolveVersion("g.h") == 1.some); auto mappedKeys = mappedPaths.mapValues!size_t(x => x.length); assert(mappedKeys.get("g") == 1.some); assert(mappedKeys.getVersion("g") == 1.some); assert(mappedKeys.resolve("g.h") == 1.some); assert(mappedKeys.resolveVersion("g.h") == 1.some);
Path tree is a tree where each node has a path assigned. Path is joined with dots which represent tree hierarchy. Each node can hold an optional value. Values are overridable, but history of values is kept, so we can analyze version number for a given node (number of times $(D_PSYMBOL put) was used with that node as target) and revert to previous version of that node as well.
Besides retrieving exact value with $(D_PSYMBOL get), we can also $(D_PSYMBOL resolve) a path. In this case if a node specified by path has no value, we fall back to parent node (with fallback to grandparent node, etc). This mode of retrieving values is very useful when using this structure as description of some other hierarchy, e.g. package structure and its related log levels.