read<T> static method

T? read<T>(
  1. String key, {
  2. T decoder(
    1. Map<String, dynamic> json
    )?,
  3. T? defaultValue,
})

Reads data from regular storage with type safety.

Use the generic type parameter to specify the expected return type. For complex objects, provide a decoder function.

Returns defaultValue if the key doesn't exist or decoding fails.

Implementation

static T? read<T>(
  String key, {
  T Function(Map<String, dynamic> json)? decoder,
  T? defaultValue,
}) {
  try {
    // Try to get value with the appropriate type
    final Object? value = _prefs.get(key);

    if (value == null) {
      return defaultValue;
    }

    // Direct type match
    if (value is T) {
      return value as T;
    }

    // Handle JSON decoding for complex types
    if (value is String && decoder != null) {
      try {
        final json = jsonDecode(value) as Map<String, dynamic>;
        return decoder(json);
      } catch (e) {
        dump('[JetStorage.read] Failed to decode JSON for key "$key": $e');
        return defaultValue;
      }
    }

    // Handle type conversions
    if (T == String) {
      return value.toString() as T;
    }

    // Try JSON decode for generic types
    if (value is String) {
      try {
        final decoded = jsonDecode(value);
        if (decoded is T) {
          return decoded;
        }
      } catch (_) {
        // Not valid JSON, return as is if it matches the type
      }
    }

    dump(
      '[JetStorage.read] Type mismatch for key "$key": expected $T but got ${value.runtimeType}',
    );
    return defaultValue;
  } catch (e, stackTrace) {
    dump(
      '[JetStorage.read] Error reading from storage: ${e.toString()}',
      stackTrace: stackTrace,
    );
    return defaultValue;
  }
}