| Index: pkg/serialization/lib/src/serialization_helpers.dart
|
| diff --git a/pkg/serialization/lib/src/serialization_helpers.dart b/pkg/serialization/lib/src/serialization_helpers.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..52072670726bb7e9d5bbea7dda8f36ba86d4aab1
|
| --- /dev/null
|
| +++ b/pkg/serialization/lib/src/serialization_helpers.dart
|
| @@ -0,0 +1,92 @@
|
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +/**
|
| + * This contains extra functions and classes useful for implementing
|
| + * serialiation. Some or all of these will be removed once the functionality is
|
| + * available in the core library.
|
| + */
|
| +library serialization_helpers;
|
| +
|
| +import 'dart:collection';
|
| +
|
| +/**
|
| + * A named function of one argument that just returns it. Useful for using
|
| + * as a default value for a function parameter or other places where you want
|
| + * to concisely provide a function that just returns its argument.
|
| + */
|
| +doNothing(x) => x;
|
| +
|
| +/** Concatenate two lists. Handle the case where one or both might be null. */
|
| +// TODO(alanknight): Remove once issue 5342 is resolved.
|
| +Iterable append(Iterable a, Iterable b) {
|
| + if (a == null) {
|
| + return (b == null) ? [] : new List.from(b);
|
| + }
|
| + if (b == null) return new List.from(a);
|
| + var result = new List.from(a);
|
| + result.addAll(b);
|
| + return result;
|
| +}
|
| +
|
| +/** Helper function for PrimitiveRule to tell which objects it applies to. */
|
| +bool isPrimitive(object) {
|
| + return identical(object, null) || object is num || object is String ||
|
| + identical(object, true) || identical(object, false);
|
| +}
|
| +
|
| +/**
|
| + * Given either an Iterable or a Map, return a map. For a Map just return it.
|
| + * For an iterable, return a Map from the index to the value at that index.
|
| + *
|
| + * Used to iterate polymorphically between List-like and Map-like things.
|
| + * For example, keysAndValues(["a", "b", "c"]).forEach((key, value) => ...);
|
| + * will loop over the key/value pairs 1/"a", 2/"b", 3/"c", as if the argument
|
| + * was a Map from integer keys to string values.
|
| + */
|
| +Map keysAndValues(x) {
|
| + if (x is Map) return x;
|
| + if (x is List) return x.asMap();
|
| + if (x is Iterable) return x.toList().asMap();
|
| + throw new ArgumentError("Invalid argument, expected Map or Iterable, got $x");
|
| +}
|
| +
|
| +/**
|
| + * Lets you iterate polymorphically between
|
| + * List-like and Map-like things, but making them behave like Lists, instead
|
| + * of behaving like Maps.
|
| + * So values(["a", "b", "c"]).forEach((value) => ...);
|
| + * will loop over the values "a", "b", "c", as if it were a List of values.
|
| + * Only supports forEach() and map() operations because that was all I needed
|
| + * for the moment.
|
| + */
|
| +Iterable values(x) {
|
| + if (x is Iterable) return x;
|
| + if (x is Map) return x.values;
|
| + throw new ArgumentError("Invalid argument, expected Map or Iterable, got $x");
|
| +}
|
| +
|
| +/**
|
| + * Iterate over [collection] and return a new collection of the same type
|
| + * where each value has been transformed by [f]. For iterables and sets, this
|
| + * is equivalent to [map]. For a Map, it returns a new Map with the same keys
|
| + * and the corresponding values transformed by [f].
|
| + */
|
| +mapValues(collection, Function f) {
|
| + if (collection is Set) return collection.map(f).toSet();
|
| + if (collection is Iterable) return collection.map(f).toList();
|
| + if (collection is Map) return new Map.fromIterables(collection.keys,
|
| + collection.values.map(f));
|
| + throw new ArgumentError("Invalid argument, expected Map or Iterable, "
|
| + "got $collection");
|
| +}
|
| +
|
| +/**
|
| + * This acts as a stand-in for some value that cannot be hashed. We can't
|
| + * just use const Object() because the compiler will fold them together.
|
| + */
|
| +class _Sentinel {
|
| + final _wrappedObject;
|
| + const _Sentinel(this._wrappedObject);
|
| +}
|
|
|