fromJson method

Snapshot fromJson(
  1. Map<String, dynamic> json
)

Converts a JSON map to a Snapshot instance.

This method parses a JSON map and creates a Snapshot, handling schema version compatibility. Currently supports schema version 1.

Parameters:

  • json: A JSON-serializable map containing snapshot data

Returns: A Snapshot instance created from the JSON data.

Throws:

Schema Version Support:

  • Version 1: Current schema format
  • Future versions: Will be handled via migration logic

Implementation

Snapshot fromJson(Map<String, dynamic> json) {
  // Validate required fields
  if (!json.containsKey('schemaVersion')) {
    throw FormatException(
      'Invalid snapshot JSON: missing "schemaVersion" field',
      json,
    );
  }

  if (!json.containsKey('appVersion')) {
    throw FormatException(
      'Invalid snapshot JSON: missing "appVersion" field',
      json,
    );
  }

  if (!json.containsKey('timestamp')) {
    throw FormatException(
      'Invalid snapshot JSON: missing "timestamp" field',
      json,
    );
  }

  if (!json.containsKey('states')) {
    throw FormatException(
      'Invalid snapshot JSON: missing "states" field',
      json,
    );
  }

  // Validate and handle schema version
  final schemaVersion = json['schemaVersion'];
  if (schemaVersion is! int) {
    throw FormatException(
      'Invalid snapshot JSON: "schemaVersion" must be an integer',
      json,
    );
  }

  if (schemaVersion != currentSchemaVersion) {
    throw FormatException(
      'Unsupported schema version: $schemaVersion. '
      'Current supported version is $currentSchemaVersion.',
      json,
    );
  }

  // Validate appVersion
  final appVersion = json['appVersion'];
  if (appVersion is! String) {
    throw FormatException(
      'Invalid snapshot JSON: "appVersion" must be a string',
      json,
    );
  }

  // Validate and parse timestamp
  final timestampString = json['timestamp'];
  if (timestampString is! String) {
    throw FormatException(
      'Invalid snapshot JSON: "timestamp" must be a string',
      json,
    );
  }

  DateTime timestamp;
  try {
    timestamp = DateTime.parse(timestampString).toUtc();
  } catch (e) {
    throw FormatException(
      'Invalid snapshot JSON: "timestamp" is not a valid ISO 8601 date string: $e',
      json,
    );
  }

  // Validate states
  final states = json['states'];
  if (states is! Map<String, dynamic>) {
    throw FormatException(
      'Invalid snapshot JSON: "states" must be a map',
      json,
    );
  }

  // Parse optional metadata
  Map<String, dynamic>? metadata;
  if (json.containsKey('metadata')) {
    final metadataValue = json['metadata'];
    if (metadataValue != null) {
      if (metadataValue is! Map<String, dynamic>) {
        throw FormatException(
          'Invalid snapshot JSON: "metadata" must be a map or null',
          json,
        );
      }
      metadata = metadataValue;
    }
  }

  return Snapshot(
    timestamp: timestamp,
    appVersion: appVersion,
    schemaVersion: schemaVersion,
    states: states,
    metadata: metadata,
  );
}