Last active
September 13, 2024 10:32
-
-
Save evaisse/e3cfed6d58a7257f50d3f13388d715f0 to your computer and use it in GitHub Desktop.
cast0r — Safe try/as and transform extension that works on any object for 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
/// Cast Or provide default value (optional or safely defaulted) | |
/// by the way, "castor" is the french word for beaver... | |
/// ``` | |
/// ___ | |
/// /. .\ | |
/// =\_t_/= | |
/// [|] | |
/// ``` | |
/// | |
extension CastOrExtension<T extends Object> on T { | |
/// Safely cast anything : | |
/// | |
/// ```dart | |
/// null.tryAs<int>()?.isFinite; // stupid but fine... | |
/// null.tryAs<int>((val) => 34)?.isFinite; // stupid but fine... | |
/// null.tryAs<int>((val) => val ?? 34)?.isFinite; // stupid but fine... | |
/// ``` | |
/// | |
B? tryCast<B extends T>([B? Function(T? val)? transform]) { | |
final that = this; | |
final valueTransformer = transform ?? (val) => that is B ? that : null; | |
try { | |
return valueTransformer(that); | |
} catch (_) { | |
// guard anything | |
return null; | |
} | |
} | |
/// It worth mentionning that [castOr] can provide a complete other type than | |
/// the original one, for example : | |
/// ```dart | |
/// "String".as<List<String?>>((val) => [val]); => List<String?> => ["String"] | |
/// ``` | |
B castOr<B>(B Function(T? val) transform) { | |
final that = this; | |
if (that is B) { | |
return that as B; | |
} else { | |
return transform(that); | |
} | |
} | |
} | |
final _samples = [ | |
null, | |
33, | |
"myString", | |
[33, "myString"] | |
]; | |
final _samplers = <String, Object? Function(Object? T)>{ | |
'`dynamic` keyword is Bad bad bad not good': (dynamic object) { | |
try { | |
// will fail :( | |
return object.tryAs<Object?>(); | |
} catch (e) { | |
return 'Ooooh myyy. Dynamic is sh**t :('; | |
} | |
}, | |
'Is null?': (object) { | |
return (object?.tryCast() == null); | |
}, | |
'Unnecessary type check': (object) { | |
// ignore: unnecessary_type_check | |
return object?.tryCast<String>() is String?; | |
}, | |
"Expect an isFinite <int>": (object) { | |
return object?.tryCast<int>()?.tryCast()?.isFinite; | |
}, | |
"Expect an alternative of the same type if null": (object) { | |
return object?.tryCast<int>()?.isFinite; | |
}, | |
"Try an alternative casting": (object) { | |
return object | |
?.tryCast<int>((val) => val is double ? val.toInt() : 34) | |
?.isFinite; | |
}, | |
"Fetch an alternative an alternative of the same type if null": (object) { | |
return object?.tryCast<int>((val) => 34)?.isFinite; | |
}, | |
"Alternative with the alternate syntax and providing a default": (object) { | |
return object | |
?.castOr<int>((that) => 43) | |
// not now we now that `u` is `int` as inferred | |
.castOr((u) => u?.isOdd ?? true ? 54 : 45) | |
.isFinite; | |
}, | |
"Providing a complete other value A.K.A transform": (object) { | |
return object | |
// map this value into a Set of int | |
?.castOr<Set<int>>((val) => {val is int ? val : 43}) | |
// and fetch it back as an int | |
.castOr<int>((val) => val?.toList().elementAtOrNull(0) ?? 34) | |
// you can provide mostly any transformation there | |
.isFinite; | |
}, | |
}; | |
void main() { | |
print(""); | |
for (final takeThat in _samples) { | |
print("Received that one : ${takeThat.runtimeType} —> $takeThat"); | |
print("——"); | |
int i = 0; | |
for (final sampler in _samplers.entries) { | |
print(' ${++i}) ${sampler.key}: ${sampler.value(takeThat)}'); | |
} | |
print(""); | |
} | |
} | |
/// ``` | |
/// ██ ██████████████▓▓██ ████ | |
/// ██▒▒██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██▒▒▒▒██ | |
/// ██▒▒██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██▒▒▒▒██ | |
/// ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ | |
/// ██▒▒▒▒▒▒██▒▒▒▒██▒▒▒▒▒▒▒▒▒▒▒▒▓▓ | |
/// ██▒▒▒▒▒▒▒▒██▒▒▒▒██▒▒▒▒▒▒▒▒▒▒▒▒██ | |
/// ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ | |
/// ██▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ | |
/// ██▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒██ ░░ | |
/// ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒██ | |
/// ██▒▒▒▒██▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒▒▒██ | |
/// ██▒▒▒▒▓▓██████████████████▓▓▒▒▒▒▒▒▒▒▒▒▓▓▒▒██ | |
/// ▓▓▒▒▒▒▒▒▓▓██ ██ ██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒██ | |
/// ██▒▒▒▒▒▒▒▒██ ██ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ | |
/// ██▒▒▒▒▒▒▒▒██ ██ ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒██ | |
/// ██▓▓▒▒▒▒▒▒▒▒██████████▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒██ | |
/// ██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓██░░██▒▒▒▒▒▒▒▒▒▒▓▓▒▒██ | |
/// ████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓██░░▒▒▒▒██▒▒▒▒▒▒▒▒▒▒▓▓▒▒██ | |
/// ████▓▓▒▒▓▓██████▓▓██░░▒▒██████▒▒▒▒▒▒▒▒▒▒▒▒▒▒██ ████████ | |
/// ██▓▓██▒▒▒▒▓▓██░░▒▒██▓▓▒▒▒▒██▒▒▒▒██▒▒▓▓▒▒██ ██▒▒▒▒▒▒▒▒██ | |
/// ██▒▒▒▒▒▒▓▓██░░▒▒▒▒▒▒██▓▓▒▒▒▒▒▒▓▓██▒▒▒▒▓▓▒▒██▒▒▓▓▓▓▒▒▓▓▒▒██ | |
/// ██▓▓▓▓▓▓██░░▒▒▒▒▒▒██▓▓██▓▓▓▓▓▓██▓▓▒▒▒▒▒▒▒▒██▓▓▒▒▓▓▓▓▓▓▓▓██ | |
/// ██████████▒▒▒▒▒▒██▓▓▓▓▓▓██████▓▓▒▒▒▒▓▓▒▒▒▒██▓▓▓▓▓▓▓▓▒▒▓▓██ | |
/// ██▓▓██░░░░██▒▒▒▒██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒██▓▓▓▓▓▓▓▓▓▓▓▓██ | |
/// ██▓▓▓▓██░░░░████▒▒██▒▒▒▒▓▓▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒██▓▓▒▒▓▓▓▓▓▓████ | |
/// ██▓▓▓▓████▓▓▓▓██▒▒██▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒██▓▓▓▓▓▓▓▓████ | |
/// ██▓▓▓▓▓▓▓▓▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓██▓▓▓▓▒▒████ | |
/// ██████▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓██████████████████████ | |
/// ██░░░░░░██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██░░░░░░░░░░░░████████ | |
/// ██▒▒██▒▒▒▒▒▒██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██▒▒▒▒▒▒██▒▒██▒▒▒▒██ | |
/// ██▓▓██████████████▓▓████████████████████████████▓▓ | |
/// | |
/// credits : https://textart.sh/topic/beaver |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment