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

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

Issue 14578008: Add a DateTimeRule to default serialization (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 months 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
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * This provides a general-purpose serialization facility for Dart objects. A 6 * This provides a general-purpose serialization facility for Dart objects. A
7 * [Serialization] is defined in terms of [SerializationRule]s and supports 7 * [Serialization] is defined in terms of [SerializationRule]s and supports
8 * reading and writing to different formats. 8 * reading and writing to different formats.
9 * 9 *
10 * ## Installing ## 10 * ## Installing ##
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 251
252 /** 252 /**
253 * When we write out data using this serialization, should we also write 253 * When we write out data using this serialization, should we also write
254 * out a description of the rules. This is on by default unless using 254 * out a description of the rules. This is on by default unless using
255 * CustomRule subclasses, in which case it requires additional setup and 255 * CustomRule subclasses, in which case it requires additional setup and
256 * is off by default. 256 * is off by default.
257 */ 257 */
258 bool get selfDescribing { 258 bool get selfDescribing {
259 // TODO(alanknight): Should this be moved to the format? 259 // TODO(alanknight): Should this be moved to the format?
260 // TODO(alanknight): Allow self-describing in the presence of CustomRule. 260 // TODO(alanknight): Allow self-describing in the presence of CustomRule.
261 // TODO(alanknight): Don't do duplicate work creating a writer and
262 // serialization here and then re-creating when we actually serialize.
261 if (_selfDescribing != null) return _selfDescribing; 263 if (_selfDescribing != null) return _selfDescribing;
262 _selfDescribing = !rules.any((x) => x is CustomRule && x is! SymbolRule); 264 var meta = ruleSerialization();
265 var w = meta.newWriter();
266 _selfDescribing = !rules.any((rule) =>
267 meta.rulesFor(rule, w, false).isEmpty);
263 return _selfDescribing; 268 return _selfDescribing;
264 } 269 }
265 270
266 /** 271 /**
267 * When we write out data using this serialization, should we also write 272 * When we write out data using this serialization, should we also write
268 * out a description of the rules. This is on by default unless using 273 * out a description of the rules. This is on by default unless using
269 * CustomRule subclasses, in which case it requires additional setup and 274 * CustomRule subclasses, in which case it requires additional setup and
270 * is off by default. 275 * is off by default.
271 */ 276 */
272 void set selfDescribing(bool value) { 277 void set selfDescribing(bool value) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 336
332 /** Set up the default rules, for lists and primitives. */ 337 /** Set up the default rules, for lists and primitives. */
333 void addDefaultRules() { 338 void addDefaultRules() {
334 addRule(new PrimitiveRule()); 339 addRule(new PrimitiveRule());
335 addRule(new ListRule()); 340 addRule(new ListRule());
336 // Both these rules apply to lists, so unless otherwise indicated, 341 // Both these rules apply to lists, so unless otherwise indicated,
337 // it will always find the first one. 342 // it will always find the first one.
338 addRule(new ListRuleEssential()); 343 addRule(new ListRuleEssential());
339 addRule(new MapRule()); 344 addRule(new MapRule());
340 addRule(new SymbolRule()); 345 addRule(new SymbolRule());
346 addRule(new DateTimeRule());
341 } 347 }
342 348
343 /** 349 /**
344 * Add a new SerializationRule [rule]. The addRuleFor method will probably 350 * Add a new SerializationRule [rule]. The addRuleFor method will probably
345 * handle most simple cases, but for adding an arbitrary rule, including 351 * handle most simple cases, but for adding an arbitrary rule, including
346 * a SerializationRule subclass which you have created, you can use this 352 * a SerializationRule subclass which you have created, you can use this
347 * method. 353 * method.
348 */ 354 */
349 void addRule(SerializationRule rule) { 355 void addRule(SerializationRule rule) {
350 rule.number = rules.length; 356 rule.number = rules.length;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 * Return a new [Reader] object for this serialization. This is useful if 393 * Return a new [Reader] object for this serialization. This is useful if
388 * you want to do something more complex with the reader than just returning 394 * you want to do something more complex with the reader than just returning
389 * the final result. 395 * the final result.
390 */ 396 */
391 Reader newReader([Format format]) => new Reader(this, format); 397 Reader newReader([Format format]) => new Reader(this, format);
392 398
393 /** 399 /**
394 * Return the list of SerializationRule that apply to [object]. For 400 * Return the list of SerializationRule that apply to [object]. For
395 * internal use, but public because it's used in testing. 401 * internal use, but public because it's used in testing.
396 */ 402 */
397 Iterable<SerializationRule> rulesFor(object, Writer w) { 403 Iterable<SerializationRule> rulesFor(object, Writer w, [create = true]) {
Jennifer Messerly 2013/05/14 23:18:33 consider: named argument here, they tend to be a b
Alan Knight 2013/05/14 23:32:55 Done.
398 // This has a couple of edge cases. 404 // This has a couple of edge cases.
399 // 1) The owning object may have indicated we should use a different 405 // 1) The owning object may have indicated we should use a different
400 // rule than the default. 406 // rule than the default.
401 // 2) We may not have a rule, in which case we lazily create a BasicRule. 407 // 2) We may not have a rule, in which case we lazily create a BasicRule.
402 // 3) Rules are allowed to say mustBePrimary, meaning that they can be used 408 // 3) Rules are allowed to say mustBePrimary, meaning that they can be used
403 // iff no other rule was chosen first. 409 // iff no other rule was chosen first.
404 // TODO(alanknight): Can the mustBePrimary mechanism be removed or changed. 410 // TODO(alanknight): Can the mustBePrimary mechanism be removed or changed.
405 // It adds an order dependency to the rules, and is messy. Reconsider in the 411 // It adds an order dependency to the rules, and is messy. Reconsider in the
406 // light of a more general mechanism for multiple rules per object. 412 // light of a more general mechanism for multiple rules per object.
407 // TODO(alanknight): Finding which rules apply seems likely to be a 413 // TODO(alanknight): Finding which rules apply seems likely to be a
408 // bottleneck, particularly with the current reflective implementation. 414 // bottleneck, particularly with the current reflective implementation.
409 // Consider how to improve it. e.g. cache the list of rules by class. But 415 // Consider how to improve it. e.g. cache the list of rules by class. But
410 // be careful of issues like rules which have arbitrary predicates. Or 416 // be careful of issues like rules which have arbitrary predicates. Or
411 // consider having the arbitrary predicates be secondary to an initial 417 // consider having the arbitrary predicates be secondary to an initial
412 // class-based lookup mechanism. 418 // class-based lookup mechanism.
413 var target, candidateRules; 419 var target, candidateRules;
414 if (object is DesignatedRuleForObject) { 420 if (object is DesignatedRuleForObject) {
415 target = object.target; 421 target = object.target;
416 candidateRules = object.possibleRules(rules); 422 candidateRules = object.possibleRules(rules);
417 } else { 423 } else {
418 target = object; 424 target = object;
419 candidateRules = rules; 425 candidateRules = rules;
420 } 426 }
421 Iterable applicable = candidateRules.where( 427 Iterable applicable = candidateRules.where(
422 (each) => each.appliesTo(target, w)); 428 (each) => each.appliesTo(target, w));
423 429
424 if (applicable.isEmpty) { 430 if (applicable.isEmpty) {
425 return [addRuleFor(target)]; 431 return create ? [addRuleFor(target)] : applicable;
426 } 432 }
427 433
428 if (applicable.length == 1) return applicable; 434 if (applicable.length == 1) return applicable;
429 var first = applicable.first; 435 var first = applicable.first;
430 var finalRules = applicable.where( 436 var finalRules = applicable.where(
431 (x) => !x.mustBePrimary || (x == first)); 437 (x) => !x.mustBePrimary || (x == first));
432 438
433 if (finalRules.isEmpty) throw new SerializationException( 439 if (finalRules.isEmpty) throw new SerializationException(
434 'No valid rule found for object $object'); 440 'No valid rule found for object $object');
435 return finalRules; 441 return finalRules;
(...skipping 23 matching lines...) Expand all
459 ..addRuleFor(new PrimitiveRule()) 465 ..addRuleFor(new PrimitiveRule())
460 ..addRuleFor(new ListRuleEssential()) 466 ..addRuleFor(new ListRuleEssential())
461 ..addRuleFor(basicRule, 467 ..addRuleFor(basicRule,
462 constructorFields: ['type', 468 constructorFields: ['type',
463 'constructorName', 469 'constructorName',
464 'constructorFields', 'regularFields', []], 470 'constructorFields', 'regularFields', []],
465 fields: []) 471 fields: [])
466 ..addRule(new NamedObjectRule()) 472 ..addRule(new NamedObjectRule())
467 ..addRule(new MirrorRule()) 473 ..addRule(new MirrorRule())
468 ..addRuleFor(new MirrorRule()) 474 ..addRuleFor(new MirrorRule())
469 ..addRuleFor(new SymbolRule()); 475 ..addRuleFor(new SymbolRule())
476 ..addRuleFor(new DateTimeRule());
470 meta.namedObjects = namedObjects; 477 meta.namedObjects = namedObjects;
471 return meta; 478 return meta;
472 } 479 }
473 480
474 /** Return true if our [namedObjects] collection has an entry for [object].*/ 481 /** Return true if our [namedObjects] collection has an entry for [object].*/
475 bool _hasNameFor(object) { 482 bool _hasNameFor(object) {
476 var sentinel = const _Sentinel(); 483 var sentinel = const _Sentinel();
477 return _nameFor(object, () => sentinel) != sentinel; 484 return _nameFor(object, () => sentinel) != sentinel;
478 } 485 }
479 486
(...skipping 10 matching lines...) Expand all
490 } 497 }
491 498
492 /** 499 /**
493 * An exception class for errors during serialization. 500 * An exception class for errors during serialization.
494 */ 501 */
495 class SerializationException implements Exception { 502 class SerializationException implements Exception {
496 final String message; 503 final String message;
497 const SerializationException([this.message]); 504 const SerializationException([this.message]);
498 toString() => "SerializationException($message)"; 505 toString() => "SerializationException($message)";
499 } 506 }
OLDNEW
« no previous file with comments | « no previous file | pkg/serialization/lib/src/serialization_rule.dart » ('j') | pkg/serialization/lib/src/serialization_rule.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698