WorldManifest.fromDocument constructor
Parse a manifest document. Throws WorldManifestError (with fix hints) on structural violations.
Implementation
factory WorldManifest.fromDocument(Map<String, dynamic> doc) {
final schema = (doc['schema'] as num?)?.toInt() ?? 0;
if (schema != schemaVersion) {
throw WorldManifestError(
'world manifest schema $schema is not $schemaVersion '
'--> fix: regenerate the world with `zfa simulate init`.',
);
}
final scenario = doc['scenario'] as String? ?? '';
if (scenario.isEmpty) {
throw const WorldManifestError(
'world manifest without a scenario name --> fix: set "scenario" '
'(the `zfa simulate --scenario` key).',
);
}
final touchpoints = (doc['touchpoints'] as List? ?? const [])
.map(
(t) => WorldTouchpoint.fromJson(Map<String, dynamic>.from(t as Map)),
)
.toList(growable: false);
if (touchpoints.isEmpty) {
throw WorldManifestError(
'world "$scenario" declares no touchpoints --> fix: declare the '
'dependency rows (External Dependencies table) and re-run '
'`zfa simulate init $scenario`.',
);
}
final storms =
(((doc['failureSchedule'] as Map<String, dynamic>? ??
const <String, dynamic>{})['storms']
as List? ??
const [])
.map(
(s) => WorldStorm.fromJson(Map<String, dynamic>.from(s as Map)),
)
.toList(growable: false));
final behaviors = (doc['behaviors'] as List? ?? const [])
.map((b) => WorldBehavior.fromJson(Map<String, dynamic>.from(b as Map)))
.toList(growable: false);
final latency = <String, WorldLatencyBands>{};
final latencyDoc = doc['latency'] as Map? ?? const {};
for (final entry in latencyDoc.entries) {
final value = entry.value;
if (value is Map) {
latency[entry.key.toString()] = WorldLatencyBands.fromJson(
Map<String, dynamic>.from(value),
);
}
}
final corpus = <String, Map<String, dynamic>>{};
final corpusDoc = doc['corpus'] as Map? ?? const {};
for (final entry in corpusDoc.entries) {
final value = entry.value;
if (value is Map) {
corpus[entry.key.toString()] = Map<String, dynamic>.from(value);
}
}
return WorldManifest(
schema: schema,
spec: (doc['spec'] as num?)?.toInt() ?? specNumber,
scenario: scenario,
feature: doc['feature'] as String? ?? '',
version: (doc['version'] as num?)?.toInt() ?? 1,
seed: (doc['time'] is Map
? ((doc['time'] as Map)['seed'] as num?)?.toInt() ?? 0
: 0),
touchpoints: touchpoints,
latency: latency,
storms: storms,
corpus: corpus,
behaviors: behaviors,
description: doc['description'] as String? ?? '',
);
}