fromJson static method
Implementation
static PluginManifest fromJson(Map<String, Object?> json) {
var version = json['version']! as int;
if (version != manifestVersion) {
throw FormatException(
'Unsupported flutterware manifest version $version '
'(this build understands $manifestVersion).',
);
}
var plugins = [
for (var p in (json['plugins']! as List).cast<Map<String, Object?>>())
PluginDeclaration.fromJson(p),
];
// Checked on the way *in*, not only on the way out. `FlutterwareConfig.use`
// refuses both of these, but a manifest does not have to have come from
// `Flutterware.configure` — and a reservation enforced on one side only is
// a convention, which is not what [Address.shellConfig] claims to be. The
// failure without this is silent either way: a duplicate id resolves one
// plugin and drops another, and an id of `config` is shadowed by the
// shell's own screen with the plugin simply unreachable.
var seen = <String>{};
for (var plugin in plugins) {
if (!seen.add(plugin.id)) {
throw FormatException('Plugin id "${plugin.id}" is declared twice.');
}
if (Address.shellOwned.contains(plugin.id)) {
throw FormatException(
'Plugin id "${plugin.id}" is reserved for one of the shell\'s own '
'screens.',
);
}
if (_duplicatePackagePath(plugin.config) case var path?) {
throw FormatException(_duplicatePackageMessage(plugin.id, path));
}
}
return PluginManifest(
plugins,
version: version,
changes: switch (json['changes']) {
Map<Object?, Object?> it => ChangesConfig.fromJson(
it.cast<String, Object?>(),
),
_ => null,
},
identity: switch (json['identity']) {
Map<Object?, Object?> it => ProjectIdentity.fromJson(
it.cast<String, Object?>(),
),
_ => null,
},
clock: switch (json['clock']) {
String it => DateTime.tryParse(it),
_ => null,
},
network: switch (json['network']) {
String it => ScenarioNetwork.values.firstWhereOrNull(
(mode) => mode.name == it,
),
_ => null,
},
);
}