Permalink
Browse files

Improve `loader` example.

  • Loading branch information...
dervus committed Feb 8, 2013
1 parent b59e4f8 commit 362660fb7f53f9cc414e4bd821532f8d0792576f
Showing with 101 additions and 23 deletions.
  1. +83 −23 examples/loader.js
  2. +18 −0 examples/loader.yaml
View
@@ -1,44 +1,104 @@
'use strict';
+var fs = require('fs');
+var path = require('path');
+var util = require('util');
var yaml = require('../lib/js-yaml');
-var cookiesType = new yaml.Type('!cookies', {
- loader: {
- kind: 'string',
- resolver: function (object /*, explicit*/) {
- return 'A ' + object + ' with some cookies!';
+// Let define a couple of classes...
+
+function Point(x, y, z) {
+ this.klass = 'Point';
+ this.x = x;
+ this.y = y;
+ this.z = z;
+}
+
+
+function Space(height, width, points) {
+ if (points) {
+ if (!points.every(function (point) { return point instanceof Point; })) {
+ throw new Error('A non-Point inside a points array!');
}
- },
- dumper: {
- kind: 'string',
- representer: function (object /*, style*/) {
- var match = /^A (.+?) with some cookies!$/.exec(object);
+ }
- if (null !== match) {
- return match[1];
+ this.klass = 'Space';
+ this.height = height;
+ this.width = width;
+ this.points = points;
+}
+
+
+// Let define YAML types to load and dump our Point/Space objects.
+
+var pointYamlType = new yaml.Type('!point', {
+ // The information used to load a Point.
+ loader: {
+ kind: 'array', // It must be an array. (sequence in YAML)
+ resolver: function (object) {
+ // It must contain exactly tree elements.
+ if (3 === object.length) {
+ return new Point(object[0], object[1], object[2]);
+
+ // Otherwise, it is NOT a Point.
} else {
return yaml.NIL;
}
}
+ },
+ // The information used to dump a Point.
+ dumper: {
+ kind: 'object', // It must be an object but not an array.
+ instanceOf: Point, // Also, it must be an instance of Point class.
+ representer: function (point) {
+ // And it should be represented in YAML as three-element sequence.
+ return [ point.x, point.y, point.z ];
+ }
}
});
-var COOKIES_SCHEMA = new yaml.Schema({
- include: [ yaml.DEFAULT_SCHEMA ],
- explicit: [ cookiesType ]
+
+var spaceYamlType = new yaml.Type('!space', {
+ loader: {
+ kind: 'object', // 'object' here means 'mapping' in YAML.
+ resolver: function (object) {
+ return new Space(object.height, object.width, object.points);
+ }
+ },
+ dumper: {
+ kind: 'object',
+ instanceOf: Space
+ // The representer is omitted here. So, Space objects will be dumped as is.
+ // That is regular mapping with three key-value pairs but with !space tag.
+ }
});
-var loaded = yaml.load('!cookies coffee', { schema: COOKIES_SCHEMA });
-var dumped = yaml.dump(loaded, { schema: COOKIES_SCHEMA });
+// After our types are defined, it's time to join them into a schema.
+
+var SPACE_SCHEMA = yaml.Schema.create([ spaceYamlType, pointYamlType ]);
+
+
+// And read a document using that schema.
+
+fs.readFile(path.join(__dirname, 'loader.yaml'), 'utf8', function (error, data) {
+ var loaded;
+
+ if (!error) {
+ loaded = yaml.load(data, { schema: SPACE_SCHEMA });
+ console.log(util.inspect(loaded, false, 20, true));
+ } else {
+ console.error(error.stack || error.message || String(error));
+ }
+});
-console.log(loaded);
-console.log(dumped);
+// There are some exports to play with this example interactively.
-// Output:
-//==============================================================================
-// A coffee with some cookies!
-// !<!cookies> "coffee"
+module.exports.Point = Point;
+module.exports.Space = Space;
+module.exports.pointYamlType = pointYamlType;
+module.exports.spaceYamlType = spaceYamlType;
+module.exports.SPACE_SCHEMA = SPACE_SCHEMA;
View
@@ -0,0 +1,18 @@
+subject: Custom types in JS-YAML
+spaces:
+- !space
+ height: 1000
+ width: 1000
+ points:
+ - !point [ 10, 43, 23 ]
+ - !point [ 165, 0, 50 ]
+ - !point [ 100, 100, 100 ]
+
+- !space
+ height: 64
+ width: 128
+ points:
+ - !point [ 12, 43, 0 ]
+ - !point [ 1, 4, 90 ]
+
+- !space {} # An empty space

0 comments on commit 362660f

Please sign in to comment.