fromSerializable<T> method
T?
fromSerializable<T>()
Attempts to convert a serialized value to type T
Implementation
T? fromSerializable<T>() {
final Object? self = this;
if (self == null) return null;
// Assert supported types early in development
final String typeString = T.toString();
assert(
_isSupportedType(typeString),
'Type $typeString is not supported for deserialization. '
'Supported types:\n'
'''• Simple types: int, double, String, bool, DateTime, Duration, Uri, Color, Object?, dynamic\n'''
'''• Simple lists: List<int>, List<double>, List<String>, List<bool>, List<DateTime>, List<Duration>, List<Color>, List<Object?>\n'''
'''• JSON map lists: List<Map<String, Object?>>, List<Map<String, dynamic>>\n'''
'''• Simple maps: Map<String, int>, Map<String, double>, Map<String, String>, '''
'''Map<String, bool>, Map<String, DateTime>, Map<String, Duration>, Map<String, Color>, Map<String, Object?>, Map<String, dynamic>\n\n'''
'''For complex nested structures, create a model class that extends BaseDataModel.''',
);
// Direct type match
if (self is T) return self as T?;
// String type handling
if (T == String) {
return self.toString() as T?;
}
// Int type handling
if (T == int) {
if (self is int) return self as T?;
if (self is double) return self.toInt() as T?;
if (self is String) return int.tryParse(self) as T?;
if (self is bool) return (self ? 1 : 0) as T?;
return null;
}
// Double type handling
if (T == double) {
if (self is double) return self as T?;
if (self is int) return self.toDouble() as T?;
if (self is String) return double.tryParse(self) as T?;
if (self is bool) return (self ? 1.0 : 0.0) as T?;
return null;
}
// Bool type handling
if (T == bool) {
if (self is bool) return self as T?;
if (self is int) return (self != 0) as T?;
if (self is double) return (self != 0.0) as T?;
if (self is String) {
final String lower = self.toLowerCase();
if (lower.compareWithoutCaseAny(<String>['true', '1', 'yes', 'on'])) {
return true as T?;
}
if (lower.compareWithoutCaseAny(<String>['false', '0', 'no', 'off'])) {
return false as T?;
}
}
return null;
}
// DateTime type handling
if (T == DateTime) {
if (self is DateTime) return self as T?;
if (self is String) {
try {
return DateTime.parse(self) as T?;
} catch (e) {
return null;
}
}
if (self is int) {
try {
return DateTime.fromMillisecondsSinceEpoch(self) as T?;
} catch (e) {
return null;
}
}
return null;
}
// Duration type handling
if (T == Duration) {
if (self is Duration) return self as T?;
if (self is int) {
try {
return Duration(microseconds: self) as T?;
} catch (e) {
return null;
}
}
if (self is String) {
final int? microseconds = int.tryParse(self);
if (microseconds != null) {
try {
return Duration(microseconds: microseconds) as T?;
} catch (e) {
return null;
}
}
}
return null;
}
// Uri type handling
if (T == Uri) {
if (self is Uri) return self as T?;
if (self is String) {
try {
return Uri.parse(self) as T?;
} catch (e) {
return null;
}
}
return null;
}
// Color type handling
if (T == Color) {
if (self is Color) return self as T?;
if (self is String) {
try {
return self.toColor() as T?;
} catch (e) {
return null;
}
}
return null;
}
if (T == Uint8List) {
if (self is Uint8List) return self as T?;
if (self is List<int>) {
try {
return Uint8List.fromList(self) as T?;
} catch (e) {
return null;
}
}
if (self is String) {
try {
// Decode Base64 string to Uint8List
return base64Decode(self) as T?;
} catch (e) {
// If Base64 decoding fails, try UTF-8 encoding as fallback
try {
return Uint8List.fromList(utf8.encode(self)) as T?;
} catch (fallbackError) {
return null;
}
}
}
return null;
}
// Map type handling - check if T is a Map type
if (typeString.startsWith('Map')) {
final Map<String, Object?>? mapResult = toMap();
if (mapResult == null) return null;
// Handle specific common map types to maintain proper typing
if (T == Map<String, int>) {
return mapResult.map(
(String key, Object? value) =>
MapEntry<String, int>(key, _safeInt(value)),
)
as T?;
}
if (T == Map<String, double>) {
return mapResult.map(
(String key, Object? value) =>
MapEntry<String, double>(key, _safeDouble(value)),
)
as T?;
}
if (T == Map<String, String>) {
return mapResult.map(
(String key, Object? value) =>
MapEntry<String, String>(key, _safeString(value)),
)
as T?;
}
if (T == Map<String, bool>) {
return mapResult.map(
(String key, Object? value) =>
MapEntry<String, bool>(key, _safeBool(value)),
)
as T?;
}
if (T == Map<String, DateTime>) {
return mapResult.map(
(String key, Object? value) =>
MapEntry<String, DateTime>(key, _safeDateTime(value)),
)
as T?;
}
if (T == Map<String, Duration>) {
return mapResult.map(
(String key, Object? value) =>
MapEntry<String, Duration>(key, _safeDuration(value)),
)
as T?;
}
if (T == Map<String, Color>) {
return mapResult.map(
(String key, Object? value) =>
MapEntry<String, Color>(key, _safeColor(value)),
)
as T?;
}
if (T == Map<String, Object?>) {
return mapResult as T?;
}
if (T == Map<String, dynamic>) {
return mapResult.cast<String, Object?>() as T?;
}
// Note: Unsupported types are caught by assert at method start
// Default fallback for simple unsupported types
return mapResult as T?;
}
// List type handling - check if T is a List type
if (typeString.startsWith('List')) {
final List<Object?>? listResult = toList();
if (listResult == null) return null;
// Handle only simple typed lists and common map lists
if (T == List<int>) {
return listResult.map(_safeInt).toList() as T?;
}
if (T == List<double>) {
return listResult.map(_safeDouble).toList() as T?;
}
if (T == List<String>) {
return listResult.map(_safeString).toList() as T?;
}
if (T == List<bool>) {
return listResult.map(_safeBool).toList() as T?;
}
if (T == List<DateTime>) {
return listResult.map(_safeDateTime).toList() as T?;
}
if (T == List<Duration>) {
return listResult.map(_safeDuration).toList() as T?;
}
if (T == List<Color>) {
return listResult.map(_safeColor).toList() as T?;
}
if (T == List<Object?>) {
return listResult as T?;
}
// Handle common map list types for JSON data
if (T == List<Map<String, Object?>>) {
return listResult.map(_safeMap).toList() as T?;
}
if (T == List<Map<String, dynamic>>) {
return listResult.map(_safeMapDynamic).toList() as T?;
}
// Note: Unsupported types are caught by assert at method start
// Default fallback for simple unsupported types
return listResult as T?;
}
// Map type handling - check if T is a Map type
if (typeString.startsWith('Map')) {
final Map<String, Object?>? mapResult = toMap();
if (mapResult == null) return null;
}
// Collection types - return as-is if type matches
if (self is T) {
return self as T;
}
// JSON string parsing for collections
if (self is String) {
try {
final Object? decoded = SafeParser.safeDecodeJson(self);
if (decoded is T) return decoded;
} catch (e) {
// Ignore JSON parsing errors
}
}
return null;
}