-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
support SharedPreferencesWithCache and SharedPreferencesAsync.
issue #75
- Loading branch information
Showing
8 changed files
with
318 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:flutter/services.dart'; | ||
import 'package:meta/meta.dart'; | ||
import 'package:rx_storage/rx_storage.dart'; | ||
import 'package:shared_preferences/shared_preferences.dart'; | ||
|
||
import '../../interface/shared_preferences_like.dart'; | ||
|
||
/// [SharedPreferencesLike]'s implementation by delegating a [SharedPreferencesAsync]. | ||
@experimental | ||
class SharedPreferencesAsyncAdapter implements SharedPreferencesLike { | ||
final SharedPreferencesAsync _prefsAsync; | ||
|
||
/// Construct a [SharedPreferencesAdapter] with [SharedPreferencesAsync]. | ||
SharedPreferencesAsyncAdapter(this._prefsAsync); | ||
|
||
@override | ||
Future<void> clear([void _]) => _prefsAsync.clear(); | ||
|
||
@override | ||
Future<bool> containsKey(String key, [void _]) => | ||
_prefsAsync.containsKey(key); | ||
|
||
@override | ||
Future<Map<String, Object?>> reload() => _prefsAsync.getAll(); | ||
|
||
@override | ||
Future<void> remove(String key, [void _]) => _prefsAsync.remove(key); | ||
|
||
@override | ||
Future<T?> read<T extends Object>(String key, Decoder<T?> decoder, | ||
[void _]) => | ||
_prefsAsync.getAll().then((map) => decoder(map[key])); | ||
|
||
@override | ||
Future<Map<String, Object?>> readAll([void _]) => _prefsAsync.getAll(); | ||
|
||
@override | ||
Future<void> write<T extends Object>( | ||
String key, T? value, Encoder<T?> encoder, | ||
[void _]) { | ||
final encodedOrFuture = encoder(value); | ||
return encodedOrFuture is Future<Object?> | ||
? encodedOrFuture.then((encoded) => _write(encoded, key, value)) | ||
: _write(encodedOrFuture, key, value); | ||
} | ||
|
||
Future<void> _write(Object? encoded, String key, Object? value) { | ||
assert(encoded is! Future<dynamic>, | ||
'The actual type of encoded value is ${encoded.runtimeType}'); | ||
|
||
if (encoded == null) { | ||
return remove(key); | ||
} | ||
if (encoded is double) { | ||
return _prefsAsync.setDouble(key, encoded); | ||
} | ||
if (encoded is int) { | ||
return _prefsAsync.setInt(key, encoded); | ||
} | ||
if (encoded is bool) { | ||
return _prefsAsync.setBool(key, encoded); | ||
} | ||
if (encoded is String) { | ||
return _prefsAsync.setString(key, encoded); | ||
} | ||
if (encoded is List<String>) { | ||
return _prefsAsync.setStringList(key, encoded); | ||
} | ||
|
||
throw PlatformException( | ||
code: SharedPreferencesLike.errorCode, | ||
message: | ||
'The encoded value of $value has the unsupported type (${encoded.runtimeType}). ' | ||
'Encoder must return a value of type FutureOr<T> ' | ||
'(where T is a supported type (double, int, bool, String or List<String>))', | ||
); | ||
} | ||
} |
104 changes: 104 additions & 0 deletions
104
lib/src/impl/async/shared_preferences_with_cache_adapter.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:flutter/foundation.dart'; | ||
import 'package:flutter/services.dart'; | ||
import 'package:rx_storage/rx_storage.dart'; | ||
import 'package:shared_preferences/shared_preferences.dart'; | ||
|
||
import '../../interface/shared_preferences_like.dart'; | ||
|
||
/// [SharedPreferencesLike]'s implementation by delegating a [SharedPreferencesWithCache]. | ||
class SharedPreferencesWithCacheAdapter implements SharedPreferencesLike { | ||
final SharedPreferencesWithCache _prefsWithCache; | ||
|
||
SharedPreferencesWithCacheAdapter._(this._prefsWithCache); | ||
|
||
static Future<T> _wrap<T>(T value) => SynchronousFuture<T>(value); | ||
|
||
static Future<T> _wrapFutureOr<T>(FutureOr<T> value) => | ||
value is Future<T> ? value : SynchronousFuture<T>(value); | ||
|
||
/// Create [SharedPreferencesAdapter] from [SharedPreferences]. | ||
static FutureOr<SharedPreferencesWithCacheAdapter> from( | ||
FutureOr<SharedPreferencesWithCache> prefsOrFuture, | ||
) => | ||
prefsOrFuture is Future<SharedPreferencesWithCache> | ||
? prefsOrFuture.then((p) => SharedPreferencesWithCacheAdapter._(p)) | ||
: SharedPreferencesWithCacheAdapter._(prefsOrFuture) | ||
as FutureOr<SharedPreferencesWithCacheAdapter>; | ||
|
||
@override | ||
Future<void> clear([void _]) => _prefsWithCache.clear(); | ||
|
||
@override | ||
Future<bool> containsKey(String key, [void _]) => | ||
_wrap(_prefsWithCache.containsKey(key)); | ||
|
||
@override | ||
Future<Map<String, Object?>> reload() => | ||
_prefsWithCache.reloadCache().then((_) => _getAllFromPrefs()); | ||
|
||
@override | ||
Future<void> remove(String key, [void _]) => _prefsWithCache.remove(key); | ||
|
||
@override | ||
Future<T?> read<T extends Object>(String key, Decoder<T?> decoder, | ||
[void _]) => | ||
_wrapFutureOr(decoder(_getFromPrefs(key))); | ||
|
||
@override | ||
Future<Map<String, Object?>> readAll([void _]) => _wrap(_getAllFromPrefs()); | ||
|
||
@override | ||
Future<void> write<T extends Object>( | ||
String key, T? value, Encoder<T?> encoder, | ||
[void _]) { | ||
final encodedOrFuture = encoder(value); | ||
return encodedOrFuture is Future<Object?> | ||
? encodedOrFuture.then((encoded) => _write(encoded, key, value)) | ||
: _write(encodedOrFuture, key, value); | ||
} | ||
|
||
Object? _getFromPrefs(String key) { | ||
final val = _prefsWithCache.get(key); | ||
return val is List ? _prefsWithCache.getStringList(key) : val; | ||
} | ||
|
||
Map<String, Object?> _getAllFromPrefs() { | ||
return { | ||
for (final k in _prefsWithCache.keys) k: _getFromPrefs(k), | ||
}; | ||
} | ||
|
||
Future<void> _write(Object? encoded, String key, Object? value) { | ||
assert(encoded is! Future<dynamic>, | ||
'The actual type of encoded value is ${encoded.runtimeType}'); | ||
|
||
if (encoded == null) { | ||
return remove(key); | ||
} | ||
if (encoded is double) { | ||
return _prefsWithCache.setDouble(key, encoded); | ||
} | ||
if (encoded is int) { | ||
return _prefsWithCache.setInt(key, encoded); | ||
} | ||
if (encoded is bool) { | ||
return _prefsWithCache.setBool(key, encoded); | ||
} | ||
if (encoded is String) { | ||
return _prefsWithCache.setString(key, encoded); | ||
} | ||
if (encoded is List<String>) { | ||
return _prefsWithCache.setStringList(key, encoded); | ||
} | ||
|
||
throw PlatformException( | ||
code: SharedPreferencesLike.errorCode, | ||
message: | ||
'The encoded value of $value has the unsupported type (${encoded.runtimeType}). ' | ||
'Encoder must return a value of type FutureOr<T> ' | ||
'(where T is a supported type (double, int, bool, String or List<String>))', | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.