set.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. 'use strict';
  2. var identity = require('../../nodes/identity.js');
  3. var Pair = require('../../nodes/Pair.js');
  4. var YAMLMap = require('../../nodes/YAMLMap.js');
  5. class YAMLSet extends YAMLMap.YAMLMap {
  6. constructor(schema) {
  7. super(schema);
  8. this.tag = YAMLSet.tag;
  9. }
  10. add(key) {
  11. let pair;
  12. if (identity.isPair(key))
  13. pair = key;
  14. else if (key &&
  15. typeof key === 'object' &&
  16. 'key' in key &&
  17. 'value' in key &&
  18. key.value === null)
  19. pair = new Pair.Pair(key.key, null);
  20. else
  21. pair = new Pair.Pair(key, null);
  22. const prev = YAMLMap.findPair(this.items, pair.key);
  23. if (!prev)
  24. this.items.push(pair);
  25. }
  26. /**
  27. * If `keepPair` is `true`, returns the Pair matching `key`.
  28. * Otherwise, returns the value of that Pair's key.
  29. */
  30. get(key, keepPair) {
  31. const pair = YAMLMap.findPair(this.items, key);
  32. return !keepPair && identity.isPair(pair)
  33. ? identity.isScalar(pair.key)
  34. ? pair.key.value
  35. : pair.key
  36. : pair;
  37. }
  38. set(key, value) {
  39. if (typeof value !== 'boolean')
  40. throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`);
  41. const prev = YAMLMap.findPair(this.items, key);
  42. if (prev && !value) {
  43. this.items.splice(this.items.indexOf(prev), 1);
  44. }
  45. else if (!prev && value) {
  46. this.items.push(new Pair.Pair(key));
  47. }
  48. }
  49. toJSON(_, ctx) {
  50. return super.toJSON(_, ctx, Set);
  51. }
  52. toString(ctx, onComment, onChompKeep) {
  53. if (!ctx)
  54. return JSON.stringify(this);
  55. if (this.hasAllNullValues(true))
  56. return super.toString(Object.assign({}, ctx, { allNullValues: true }), onComment, onChompKeep);
  57. else
  58. throw new Error('Set items must all have null values');
  59. }
  60. static from(schema, iterable, ctx) {
  61. const { replacer } = ctx;
  62. const set = new this(schema);
  63. if (iterable && Symbol.iterator in Object(iterable))
  64. for (let value of iterable) {
  65. if (typeof replacer === 'function')
  66. value = replacer.call(iterable, value, value);
  67. set.items.push(Pair.createPair(value, null, ctx));
  68. }
  69. return set;
  70. }
  71. }
  72. YAMLSet.tag = 'tag:yaml.org,2002:set';
  73. const set = {
  74. collection: 'map',
  75. identify: value => value instanceof Set,
  76. nodeClass: YAMLSet,
  77. default: false,
  78. tag: 'tag:yaml.org,2002:set',
  79. createNode: (schema, iterable, ctx) => YAMLSet.from(schema, iterable, ctx),
  80. resolve(map, onError) {
  81. if (identity.isMap(map)) {
  82. if (map.hasAllNullValues(true))
  83. return Object.assign(new YAMLSet(), map);
  84. else
  85. onError('Set items must all have null values');
  86. }
  87. else
  88. onError('Expected a mapping for this tag');
  89. return map;
  90. }
  91. };
  92. exports.YAMLSet = YAMLSet;
  93. exports.set = set;