I need to be able to bind branches to my figtree that can contain their own figs themselves.
Add NewBranch support to figtree allowing a figTree to contain child figTree instances in a map[string]*figTree data structure, with a configurable maximum depth enforced at runtime.
Developer Experience
When using branches in figtree, they should provide the same essence of the figtree, in a map[string]*figTree data structure within the figTree itself.
package main
import (
"github.com/andreimerlescu/figtree/v2"
)
func main(){
figs := figtree.Grow()
figs.NewString("name", "", "your name")
figsdb := figs.NewBranch("db")
figsdb.NewString("host", "", "database host")
figsdb.NewString("user", "", "database user")
figsdb.NewString("pass", "", "database pass")
figsdb.NewString("name", "", "name of the database")
figsdb.WithValidator("host", figtree.AssureStringNotEmpty)
figsdb.WithValidator("user", figtree.AssureStringNotEmpty)
figsdb.WithValidator("pass", figtree.AssureStringNotEmpty)
figsdb.WithValidator("name", figtree.AssureStringNotEmpty)
err := figs.Parse()
if err != nil {
panic(err)
}
name := figs.String("name")
dbHost := figs.Branch("db").String("host")
dbUser := figs.Branch("db").String("user")
dbPass := figs.Branch("db").String("pass")
dbName := figs.Branch("db").String("name")
}
JSON Files
{
"name": "andrei",
"db": {
"host": "localhost",
"user": "username",
"pass": "",
"database": "dev_db_appname"
}
}
This should result in a Validation error due to the JSON present has a bad value in the pass field due to "", which is an empty string that is explicitly not allowed by figtree.AssureStringNotEmpty.
YAML Files
---
name: andrei
db:
host: localhost
user: username
pass: notpass
database: dev_db_appname
Ini Files
The root level / global level of the figtree is the [default] section.
CLI .ini Universal App: goini
[default]
name=andrei
[db]
host=localhost
user=username
pass=notpass
database=dev_db_appname
Advanced Usages of Branches
- Branches get their own rules and validators attached to their own properties.
- Branches are separate figtree's reference by parent-child relationship.
Branch Behavior
- Each branch is its own figTree held in map[string]*figTree on the parent
- Branches inherit the parent’s shared mutationsCh — all mutations funnel to the root channel with Mutation.Branch []string carrying the path
- Branches get their own rules, validators, and callbacks scoped to their own figs
- figs.Branch("db") returns a Plant interface — all figtree methods apply
Accessors
type Fig interface {
// MODIFY ALL TYPES
String(key string) string
Int(key string) int
Int64(key string) int64
Float(key string) Float64
// ... etc.
}
GetValue would accept a key that has figtree.SeparatorGetValue string char (like "," or "|") that can be "db.host" and then it would expand into .Branch("db").String("host").
Limitations
Intentionally program a limit of 3-deep permitted. This means that if you try to do:
// Permitted
figs := figtree.New()
figsdbs := figs.NewBranch("databases")
figsmysql := figsdbs.NewBranch("mysql")
figspgsql := figsdbs.NewBranch("pgsql")
figsmongo := figsdbs.NewBranch("mongo")
figscockroach := figsdbs.NewBranch("cockroach")
// Not Permitted
figs := figtree.New()
figsdbs := figs.NewBranch("databases") // 1st level okay
figsmysql := figsdbs.NewBranch("mysql") // 2nd level okay
mysqlproperties := figsmysql.NewBranch("properties") // 3rd level okay
globalproperties := mysqlproperties.NewBranch("globalproperties") // panic here
Fig Tree Limitations
Design in this test a scenario where the figtree being accessed and tested has the following conditions:
- 100 root level properties that are a blend of the different types provided
- 100 branches
// 1st level okay
- 50 branches
// 2nd level okay
- 25 branches
// 3rd level okay
This represents an absolutely MASSIVE application. 125,100 configurable properties is excessive, but in the scope of the test, the goal is to measure how figtree performs over its memory footprint, validating the tree, its benchmark, various callback scenarios, and more.
In this test, the developer should be able to read through the source code and see the figtree built out with 125K properties in a manner that is programmatically sound and not excessively verbose as its testing performance of the tree, accuracy of the random strings, and 100% success rates in their test coverage.
Closing Notes
Ultimately, this shouldn't be too complex. You're basically taking that which is figtree and recursively allowing it to be assigned via branches with a 3-degree rule applied. The "3" of the "3-degree" rule itself can be a configurable property. But its not recommended to go above 3 because poorly designed applications can mushroom out of control quickly if you have too many tested properties. In my professional experience, I've demanded as deep as 7 degrees, and for that figtree.MaxBranchDepth = 3 will default as a variable package level - but can be expanded. It's recursive. So if its set to 7, then even the sub-trees will have up to 7.
Another thing to consider is in the performance testing establishing a ceiling on the number of figs that the tree can harvest. Effectively, when the figtree was created, it had a predetermined number of figs that it could harvest in its entire lifetime. The Harvest: property in the Config struct ultimately offers opportunity to programmatically determine recommended values of this. So if the default or value is too low, a warning is provided to the user informing them of the misconfiguration of the runtime.
I need to be able to bind branches to my
figtreethat can contain their ownfigsthemselves.Add NewBranch support to figtree allowing a figTree to contain child figTree instances in a map[string]*figTree data structure, with a configurable maximum depth enforced at runtime.
Developer Experience
When using branches in
figtree, they should provide the same essence of the figtree, in amap[string]*figTreedata structure within thefigTreeitself.JSON Files
{ "name": "andrei", "db": { "host": "localhost", "user": "username", "pass": "", "database": "dev_db_appname" } }This should result in a Validation error due to the JSON present has a bad value in the
passfield due to"", which is an empty string that is explicitly not allowed byfigtree.AssureStringNotEmpty.YAML Files
Ini Files
The root level / global level of the figtree is the
[default]section.Advanced Usages of Branches
Branch Behavior
Accessors
GetValuewould accept akeythat hasfigtree.SeparatorGetValuestring char (like "," or "|") that can be "db.host" and then it would expand into.Branch("db").String("host").Limitations
Intentionally program a limit of 3-deep permitted. This means that if you try to do:
Fig Tree Limitations
Design in this test a scenario where the figtree being accessed and tested has the following conditions:
// 1st level okay// 2nd level okay// 3rd level okayThis represents an absolutely MASSIVE application. 125,100 configurable properties is excessive, but in the scope of the test, the goal is to measure how figtree performs over its memory footprint, validating the tree, its benchmark, various callback scenarios, and more.
In this test, the developer should be able to read through the source code and see the figtree built out with 125K properties in a manner that is programmatically sound and not excessively verbose as its testing performance of the tree, accuracy of the random strings, and 100% success rates in their test coverage.
Closing Notes
Ultimately, this shouldn't be too complex. You're basically taking that which is figtree and recursively allowing it to be assigned via branches with a 3-degree rule applied. The "3" of the "3-degree" rule itself can be a configurable property. But its not recommended to go above 3 because poorly designed applications can mushroom out of control quickly if you have too many tested properties. In my professional experience, I've demanded as deep as 7 degrees, and for that
figtree.MaxBranchDepth = 3will default as a variable package level - but can be expanded. It's recursive. So if its set to 7, then even the sub-trees will have up to 7.Another thing to consider is in the performance testing establishing a ceiling on the number of figs that the tree can harvest. Effectively, when the figtree was created, it had a predetermined number of figs that it could harvest in its entire lifetime. The
Harvest:property in theConfigstruct ultimately offers opportunity to programmatically determine recommended values of this. So if the default or value is too low, a warning is provided to the user informing them of the misconfiguration of the runtime.