library _youtube_explode.extensions; import '../reverse_engineering/cipher/cipher_operations.dart'; /// Utility for Strings. extension StringUtility on String { /// Parses this value as int stripping the non digit characters, /// returns null if this fails. int parseInt() => int.tryParse(this?.stripNonDigits()); /// Returns null if this string is whitespace. String get nullIfWhitespace => trim().isEmpty ? null : this; /// Returns true if the string is null or empty. bool get isNullOrWhiteSpace { if (this == null) { return true; } if (trim().isEmpty) { return true; } return false; } /// Returns null if this string is a whitespace. String substringUntil(String separator) => substring(0, indexOf(separator)); /// String substringAfter(String separator) => substring(indexOf(separator) + separator.length); static final _exp = RegExp(r'\D'); /// Strips out all non digit characters. String stripNonDigits() => replaceAll(_exp, ''); /// String extractJson() { var buffer = StringBuffer(); var depth = 0; for (var i = 0; i < length; i++) { var ch = this[i]; var chPrv = i > 0 ? this[i - 1] : ''; buffer.write(ch); if (ch == '{' && chPrv != '\\') { depth++; } else if (ch == '}' && chPrv != '\\') { depth--; } if (depth == 0) { break; } } return buffer.toString(); } } /// List decipher utility. extension ListDecipher on Iterable { /// Apply every CipherOperation on the [signature] String decipher(String signature) { for (var operation in this) { signature = operation.decipher(signature); } return signature; } } /// List Utility. extension ListUtil on Iterable { /// Returns the first element of a list or null if empty. E get firstOrNull { if (length == 0) { return null; } return first; } /// Same as [elementAt] but if the index is higher than the length returns /// null E elementAtSafe(int index) { if (index >= length) { return null; } return elementAt(index); } } /// Uri utility extension UriUtility on Uri { /// Returns a new Uri with the new query parameters set. Uri setQueryParam(String key, String value) { var query = Map.from(queryParameters); query[key] = value; return replace(queryParameters: query); } } /// extension GetOrNull on Map { /// Get a value from a map V getValue(K key) { var v = this[key]; if (v == null) { return null; } return v; } } /// extension GetOrNullMap on Map { /// Get a map inside a map Map get(String key) { var v = this[key]; if (v == null) { return null; } return v; } /// Get a value inside a map. /// If it is null this returns null, if of another type this throws. T getT(String key) { var v = this[key]; if (v == null) { return null; } if (v is! T) { throw Exception('Invalid type: ${v.runtimeType} should be $T'); } return v; } /// Get a List>> from a map. List> getList(String key) { var v = this[key]; if (v == null) { return null; } if (v is! List) { throw Exception('Invalid type: ${v.runtimeType} should be of type List'); } return (v.toList() as List).cast>(); } } /// extension UriUtils on Uri { /// Uri replaceQueryParameters(Map parameters) { var query = Map.from(queryParameters); query.addAll(parameters); return replace(queryParameters: query); } } /// Parse properties with `runs` method. extension RunsParser on List { String parseRuns() => this?.map((e) => e['text'])?.join() ?? ''; }