The %include notation lets one file draw defaults from another. Fson::load resolves it automatically.
// service.fson
{
%include "base.fson", // base's members fill in as defaults
timeout: 60 // ... but this host value wins over base's
}
auto result = Fson::load( "service.fson" );
result.document->getInteger( "timeout", 0 ); // 60 (host wins)
result.document->getInteger( "retries", 0 ); // from base.fson
The merged view vs. what save() writes
The query view is the merged result (host over base, shallow). But save() writes only the host file back: the %include line is reproduced verbatim and base's values are not copied in. Programmatic setPath() overrides land only in the host file.
Alias form
{
%include "secrets.fson" as vault,
}
binds the whole root value of secrets.fson under the key vault (the target root need not be an object). Query it as vault.password.
Provenance — where did a value come from?
result.document->isLocal( "timeout" ); // true (defined in the host)
auto p = result.document->provenanceOf( "retries" );
// p->sourceFile → canonical path of base.fson
// p->localPath → "retries" (its path WITHIN base.fson — differs for aliases)
auto all = result.document->provenanceMap(); // every resolved top-level key
The dependency set (for reloads)
for( auto const& file : result.dependencySet ) // host + every include, sorted
watch( file );
// or, without keeping the document:
std::set<std::string> files = Fson::dependenciesOf( "service.fson" );
Edge cases, never thrown
- Cycles (
a→b→a) are reported as an error and broken; the non-cyclic content still loads. - A missing target is an error, not an exception.
--%include "…"is kept structurally but not resolved.
Continue with Reloading Changed Files.

