Skip to content

Cleanup contents of util #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 20, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 10 additions & 86 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:collection/collection.dart';

Expand All @@ -29,107 +28,32 @@ Map<K, V> updateMap<K, V>(Map<K, V> original, Map<K, V> updates) {
/// //=> "foo=bar&baz=bang"
String mapToQuery(Map<String, String> map, {Encoding encoding}) {
var pairs = <List<String>>[];
map.forEach((key, value) =>
pairs.add([Uri.encodeQueryComponent(key, encoding: encoding),
Uri.encodeQueryComponent(value, encoding: encoding)]));
map.forEach((key, value) => pairs.add([
Uri.encodeQueryComponent(key, encoding: encoding),
Uri.encodeQueryComponent(value, encoding: encoding)
]));
return pairs.map((pair) => "${pair[0]}=${pair[1]}").join("&");
}

/// Like [String.split], but only splits on the first occurrence of the pattern.
/// This will always return an array of two elements or fewer.
///
/// split1("foo,bar,baz", ","); //=> ["foo", "bar,baz"]
/// split1("foo", ","); //=> ["foo"]
/// split1("", ","); //=> []
List<String> split1(String toSplit, String pattern) {
if (toSplit.isEmpty) return <String>[];

var index = toSplit.indexOf(pattern);
if (index == -1) return [toSplit];
return [
toSplit.substring(0, index),
toSplit.substring(index + pattern.length)
];
}


/// A regular expression that matches strings that are composed entirely of
/// ASCII-compatible characters.
final RegExp _ASCII_ONLY = new RegExp(r"^[\x00-\x7F]+$");
final RegExp _asciiOnly = new RegExp(r"^[\x00-\x7F]+$");

/// Returns whether [string] is composed entirely of ASCII-compatible
/// characters.
bool isPlainAscii(String string) => _ASCII_ONLY.hasMatch(string);
bool isPlainAscii(String string) => _asciiOnly.hasMatch(string);

/// Converts [input] into a [Uint8List].
/// Pipes all data and errors from [stream] into [sink].
///
/// If [input] is a [TypedData], this just returns a view on [input].
Uint8List toUint8List(List<int> input) {
if (input is Uint8List) return input;
if (input is TypedData) {
// TODO(nweiz): remove "as" when issue 11080 is fixed.
return new Uint8List.view((input as TypedData).buffer);
}
return new Uint8List.fromList(input);
}

/// Calls [onDone] once [stream] (a single-subscription [Stream]) is finished.
/// The return value, also a single-subscription [Stream] should be used in
/// place of [stream] after calling this method.
Stream<T> onDone<T>(Stream<T> stream, void onDone()) =>
stream.transform(new StreamTransformer.fromHandlers(handleDone: (sink) {
sink.close();
onDone();
}));

// TODO(nweiz): remove this when issue 7786 is fixed.
/// Pipes all data and errors from [stream] into [sink]. When [stream] is done,
/// [sink] is closed and the returned [Future] is completed.
Future store(Stream stream, EventSink sink) {
var completer = new Completer();
stream.listen(sink.add,
onError: sink.addError,
onDone: () {
sink.close();
completer.complete();
});
return completer.future;
}

/// Pipes all data and errors from [stream] into [sink]. Completes [Future] once
/// [stream] is done. Unlike [store], [sink] remains open after [stream] is
/// done.
/// Completes [Future] once [stream] is done. Unlike [store], [sink] remains
/// open after [stream] is done.
Future writeStreamToSink(Stream stream, EventSink sink) {
var completer = new Completer();
stream.listen(sink.add,
onError: sink.addError,
onDone: () => completer.complete());
onError: sink.addError, onDone: () => completer.complete());
return completer.future;
}

/// A pair of values.
class Pair<E, F> {
E first;
F last;

Pair(this.first, this.last);

String toString() => '($first, $last)';

bool operator==(other) {
if (other is! Pair) return false;
return other.first == first && other.last == last;
}

int get hashCode => first.hashCode ^ last.hashCode;
}

/// Configures [future] so that its result (success or exception) is passed on
/// to [completer].
void chainToCompleter(Future future, Completer completer) {
future.then(completer.complete, onError: completer.completeError);
}

/// Returns the header with the given [name] in [headers].
///
/// This works even if [headers] is `null`, or if it's not yet a
Expand Down