Line data Source code
1 : part of flutter_data; 2 : 3 : extension IterableX<T> on Iterable<T> { 4 1 : @protected 5 : @visibleForTesting 6 2 : T? get safeFirst => isNotEmpty ? first : null; 7 1 : @protected 8 : @visibleForTesting 9 2 : bool containsFirst(T model) => safeFirst == model; 10 1 : @protected 11 : @visibleForTesting 12 1 : List<T> toImmutableList() => List.unmodifiable(this); 13 : } 14 : 15 : extension IterableNullX<T> on Iterable<T?> { 16 1 : @protected 17 : @visibleForTesting 18 3 : Iterable<T> get filterNulls => where((elem) => elem != null).cast(); 19 : } 20 : 21 : extension StringUtilsX on String { 22 1 : String capitalize() => 23 5 : isEmpty ? '' : '${this[0].toUpperCase()}${substring(1)}'; 24 : 25 1 : String decapitalize() => 26 5 : isEmpty ? '' : '${this[0].toLowerCase()}${substring(1)}'; 27 : 28 2 : String pluralize() => inflection.pluralize(this); 29 : 30 2 : String singularize() => inflection.singularize(this); 31 : 32 2 : Uri get asUri => Uri.parse(this); 33 : 34 1 : String denamespace() { 35 : // need to re-join with : in case there were other :s in the text 36 3 : return (split(':')..removeAt(0)).join(':'); 37 : } 38 : 39 1 : String detypify() { 40 : // need to re-join with # in case there were other #s in the id 41 3 : return (split('#')..removeAt(0)).join('#'); 42 : } 43 : } 44 : 45 : class StringUtils { 46 1 : @protected 47 : @visibleForTesting 48 : static String namespace(String prefix, String text) { 49 : assert(!prefix.contains(':')); 50 1 : return '$prefix:$text'; 51 : } 52 : 53 1 : @protected 54 : @visibleForTesting 55 : static String typify(String type, dynamic id) { 56 : assert(!type.contains('#')); 57 1 : return '$type#$id'; 58 : } 59 : } 60 : 61 : extension MapUtilsX<K, V> on Map<K, V> { 62 1 : @protected 63 : @visibleForTesting 64 3 : Map<K, V> operator &(Map<K, V>? more) => {...this, ...?more}; 65 : 66 1 : @protected 67 : @visibleForTesting 68 1 : Map<K, V> get filterNulls => { 69 1 : for (final e in entries) 70 4 : if (e.value != null) e.key: e.value 71 : }; 72 : } 73 : 74 : extension UriUtilsX on Uri { 75 1 : Uri operator /(String path) { 76 4 : return replace(path: path_helper.normalize('/${this.path}/$path')); 77 : } 78 : 79 2 : Uri operator &(Map<String, dynamic> params) => params.isNotEmpty 80 1 : ? replace( 81 3 : queryParameters: queryParameters & _flattenQueryParameters(params)) 82 : : this; 83 : } 84 : 85 1 : Map<String, String> _flattenQueryParameters(Map<String, dynamic> params) { 86 4 : return params.entries.fold<Map<String, String>>({}, (acc, e) { 87 2 : if (e.value is Map<String, dynamic>) { 88 3 : for (final e2 in (e.value as Map<String, dynamic>).entries) { 89 6 : acc['${e.key}[${e2.key}]'] = e2.value.toString(); 90 : } 91 : } else { 92 4 : acc[e.key] = e.value.toString(); 93 : } 94 : return acc; 95 : }); 96 : }