PluginEntry.fromJson constructor
swiftpm/alignment/android are null in the JSON for a plugin whose
checks couldn't run (SPEC §3.1.2-3: "never omitted" but null on
failure) — parsed here as an all-null sentinel rather than a missing
key, since errors (checked first by every grading function) is
always non-empty whenever they're null.
Implementation
factory PluginEntry.fromJson(Map<String, dynamic> json) => PluginEntry(
name: json['name'] as String,
// Null in the JSON when the package-info fetch failed (recorded in
// errors) — every caller displays this directly, so fall back to a
// placeholder rather than widening the type to String?.
version: json['version'] as String? ?? 'unknown',
published: json['published'] as String?,
downloadCount30Days: json['downloadCount30Days'] as int?,
likeCount: json['likeCount'] as int?,
swiftpm: json['swiftpm'] == null
? const SwiftPmInfo(tag: null, archive: null, agrees: null, checkedPackage: null)
: SwiftPmInfo.fromJson(json['swiftpm'] as Map<String, dynamic>),
alignment: json['alignment'] == null
? const AlignmentInfo(checkedPackage: null, soFiles: [])
: AlignmentInfo.fromJson(json['alignment'] as Map<String, dynamic>),
android: json['android'] == null
? const AndroidInfo(checkedPackage: null, compileSdk: null, agp: null, ndk: null)
: AndroidInfo.fromJson(json['android'] as Map<String, dynamic>),
errors: [for (final e in (json['errors'] as List)) e as String],
// Null for snapshots taken before this field existed (additive,
// schemaVersion stays 1).
search: [for (final s in (json['search'] as List? ?? const [])) s as String],
);