94 lines
3 KiB
JavaScript
94 lines
3 KiB
JavaScript
|
import { isMap, isPair, isScalar } from '../../nodes/identity.js';
|
||
|
import { Pair, createPair } from '../../nodes/Pair.js';
|
||
|
import { YAMLMap, findPair } from '../../nodes/YAMLMap.js';
|
||
|
|
||
|
class YAMLSet extends YAMLMap {
|
||
|
constructor(schema) {
|
||
|
super(schema);
|
||
|
this.tag = YAMLSet.tag;
|
||
|
}
|
||
|
add(key) {
|
||
|
let pair;
|
||
|
if (isPair(key))
|
||
|
pair = key;
|
||
|
else if (key &&
|
||
|
typeof key === 'object' &&
|
||
|
'key' in key &&
|
||
|
'value' in key &&
|
||
|
key.value === null)
|
||
|
pair = new Pair(key.key, null);
|
||
|
else
|
||
|
pair = new Pair(key, null);
|
||
|
const prev = findPair(this.items, pair.key);
|
||
|
if (!prev)
|
||
|
this.items.push(pair);
|
||
|
}
|
||
|
/**
|
||
|
* If `keepPair` is `true`, returns the Pair matching `key`.
|
||
|
* Otherwise, returns the value of that Pair's key.
|
||
|
*/
|
||
|
get(key, keepPair) {
|
||
|
const pair = findPair(this.items, key);
|
||
|
return !keepPair && isPair(pair)
|
||
|
? isScalar(pair.key)
|
||
|
? pair.key.value
|
||
|
: pair.key
|
||
|
: pair;
|
||
|
}
|
||
|
set(key, value) {
|
||
|
if (typeof value !== 'boolean')
|
||
|
throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`);
|
||
|
const prev = findPair(this.items, key);
|
||
|
if (prev && !value) {
|
||
|
this.items.splice(this.items.indexOf(prev), 1);
|
||
|
}
|
||
|
else if (!prev && value) {
|
||
|
this.items.push(new Pair(key));
|
||
|
}
|
||
|
}
|
||
|
toJSON(_, ctx) {
|
||
|
return super.toJSON(_, ctx, Set);
|
||
|
}
|
||
|
toString(ctx, onComment, onChompKeep) {
|
||
|
if (!ctx)
|
||
|
return JSON.stringify(this);
|
||
|
if (this.hasAllNullValues(true))
|
||
|
return super.toString(Object.assign({}, ctx, { allNullValues: true }), onComment, onChompKeep);
|
||
|
else
|
||
|
throw new Error('Set items must all have null values');
|
||
|
}
|
||
|
static from(schema, iterable, ctx) {
|
||
|
const { replacer } = ctx;
|
||
|
const set = new this(schema);
|
||
|
if (iterable && Symbol.iterator in Object(iterable))
|
||
|
for (let value of iterable) {
|
||
|
if (typeof replacer === 'function')
|
||
|
value = replacer.call(iterable, value, value);
|
||
|
set.items.push(createPair(value, null, ctx));
|
||
|
}
|
||
|
return set;
|
||
|
}
|
||
|
}
|
||
|
YAMLSet.tag = 'tag:yaml.org,2002:set';
|
||
|
const set = {
|
||
|
collection: 'map',
|
||
|
identify: value => value instanceof Set,
|
||
|
nodeClass: YAMLSet,
|
||
|
default: false,
|
||
|
tag: 'tag:yaml.org,2002:set',
|
||
|
createNode: (schema, iterable, ctx) => YAMLSet.from(schema, iterable, ctx),
|
||
|
resolve(map, onError) {
|
||
|
if (isMap(map)) {
|
||
|
if (map.hasAllNullValues(true))
|
||
|
return Object.assign(new YAMLSet(), map);
|
||
|
else
|
||
|
onError('Set items must all have null values');
|
||
|
}
|
||
|
else
|
||
|
onError('Expected a mapping for this tag');
|
||
|
return map;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
export { YAMLSet, set };
|