Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(412)

Side by Side Diff: pkg/serialization/lib/src/serialization_helpers.dart

Issue 11293283: Initial version of a serialization framework (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * This contains extra functions and classes useful for implementing
7 * serialiation. Some or all of these will be removed once the functionality is
8 * available in the core library.
9 */
10 library serialization_helpers;
11 import 'polyfill_identity_set.dart';
12
13 /**
14 * A named function of one argument that just returns it. Useful for using
15 * as a default value for a function parameter or other places where you want
16 * to concisely provide a function that just returns its argument.
17 */
18 doNothing(x) => x;
19
20 /** Concatenate two lists. Handle the case where one or both might be null. */
21 // TODO(alanknight): Remove once issue 5342 is resolved.
22 List append(List a, List b) {
23 if (a == null) {
24 return (b == null) ? [] : new List.from(b);
25 }
26 if (b == null) return new List.from(a);
27 var result = new List.from(a);
28 result.addAll(b);
29 return result;
30 }
31
32 /**
33 * Return a sorted version of [aCollection], using the default sort criterion.
34 * Always returns a List, regardless of the type of [aCollection].
35 */
36 List sorted(aCollection) {
37 var result = new List.from(aCollection);
38 result.sort();
39 return result;
40 }
41
42 /**
43 * Be able to iterate polymorphically between List-like and Map-like things.
44 * For example, keysAndValues(["a", "b", "c"]).forEach((key, value) => ...);
45 * will loop over the key/value pairs 1/"a", 2/"b", 3/"c", as if the argument
46 * was a Map from integer keys to string values.
47 * Only supports forEach() and map() operations because that was all the code
48 * needed for the moment.
49 */
50 MapLikeIterable keysAndValues(x) {
51 if (x is Map) return new MapLikeIterableForMap(x);
52 if (x is Iterable) return new MapLikeIterableForList(x);
53 throw new ArgumentError("Invalid argument");
54 }
55
56 /**
57 * A class for iterating over things as if they were Maps, which primarily
58 * means that forEach() and map() pass two arguments, and map() returns a new
59 * Map with the same keys as [collection] and values which have been transformed
60 * by the argument to map().
61 */
62 abstract class MapLikeIterable {
63 MapLikeIterable(this.collection);
64 final collection;
65
66 /** Iterate over the collection, passing both key and value parameters. */
67 void forEach(Function f);
68
69 /**
70 * Return a new collection whose keys are the same as [collection], but whose
71 * values are the result of applying [f] to the key/value pairs. So, if
72 * [collection] is a List, it will be the same as the map() method if the
73 * [key] parameter wasn't passed.
74 */
75 map(Function f) {
76 var result = copyEmpty();
77 forEach((key, value) {
78 result[key] = f(key, value);
79 });
80 return result;
81 }
82
83 /**
84 * Return an empty copy of our collection. Very limited, only knows enough
85 * to return a Map or List as appropriate.
86 */
87 copyEmpty();
88 }
89
90
91
92 class MapLikeIterableForMap extends MapLikeIterable {
93 MapLikeIterableForMap(collection) : super(collection);
94
95 void forEach(Function f) { collection.forEach(f);}
96 Map copyEmpty() => new Map();
97 }
98
99 class MapLikeIterableForList extends MapLikeIterable {
100 MapLikeIterableForList(collection) : super(collection);
101
102 void forEach(f) {
103 Iterator iterator = collection.iterator();
104 for (var i = 0; i < collection.length; i++) {
105 f(i, iterator.next());
106 }
107 }
108
109 List copyEmpty() => new List(collection.length);
110 }
111
112 /**
113 * An inverse of MapLikeIterable. Lets you iterate polymorphically between
114 * List-like and Map-like things, but making them behave like Lists, instead
115 * of behaving like Maps.
116 * So values(["a", "b", "c"]).forEach((value) => ...);
117 * will loop over the values "a", "b", "c", as if it were a List of values.
118 * Only supports forEach() and map() operations because that was all I needed
119 * for the moment.
120 */
121 values(x) {
122 if (x is Iterable) return x;
123 if (x is Map) return new ListLikeIterable(x);
124 throw new ArgumentError("Invalid argument");
125 }
126
127 /**
128 * A class for iterating over things as if they were Lists, which primarily
129 * means that forEach passes one argument, and map() returns a new Map
130 * with the same keys as [collection] and values which haev been transformed
131 * by the argument to map().
132 */
133 class ListLikeIterable {
134 ListLikeIterable(this.collection);
135 final Map collection;
136
137 /** Iterate over the collection, passing just the value parameters. */
138 forEach(f) {
139 collection.forEach((key, value) => f(value));
140 }
141
142 /**
143 * Return a new collection whose keys are the same as [collection], but whose
144 * values are the result of applying [f] to the key/value pairs. So, if
145 * [collection] is a List, it will be the same as if map() had been called
146 * directly on [collection].
147 */
148 map(Function f) {
149 var result = new Map();
150 collection.forEach((key, value) => result[key] = f(value));
151 return result;
152 }
153
154 /**
155 * Return an iterator that behaves like a List iterator, taking one parameter.
156 */
157 Iterator iterator() => collection.values.iterator();
158 }
159
160 /**
161 * This acts as a stand-in for some value that cannot be hashed. We can't
162 * just use const Object() because the compiler will fold them together.
163 */
164 class _Sentinel {
165 final _wrappedObject;
166 const _Sentinel(this._wrappedObject);
167 }
168
169 /**
170 * This provides an identity map which allows true, false, and null as
171 * valid keys. It does this by special casing them and using some other
172 * known object as the key instead.
173 */
174 class IdentityMapPlus<K, V> extends IdentityMap {
175 final trueish = const _Sentinel(true);
176 final falseish = const _Sentinel(false);
177 final nullish = const _Sentinel(null);
178
179 wrap(x) {
180 if (x == true) return trueish;
181 if (x == false) return falseish;
182 if (x == null) return nullish;
183 return x;
184 }
185
186 unwrap(x) {
187 if (x is _Sentinel) return x._wrappedObject;
188 return x;
189 }
190
191 operator [](key) => super[wrap(key)];
192 operator []=(key, value) => super[wrap(key)] = value;
193
194 putIfAbsent(key, ifAbsent) => super.putIfAbsent(wrap(key), ifAbsent);
195
196 containsKey(key) => super.containsKey(wrap(key));
197 forEach(f) => super.forEach((key, value) => f(unwrap(key), value));
198 remove(key) => super.remove(unwrap(key));
199 /**
200 * Note that keys is a very inefficient operation for this type. Don't do it.
201 */
202 get keys => super.keys.map((x) => unwrap(x));
203 }
204
205
OLDNEW
« no previous file with comments | « pkg/serialization/lib/src/reader_writer.dart ('k') | pkg/serialization/lib/src/serialization_rule.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698