You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.9 KiB
97 lines
2.9 KiB
import { stringifyCollection } from '../stringify/stringifyCollection.js'; |
|
import { Collection } from './Collection.js'; |
|
import { SEQ, isScalar } from './Node.js'; |
|
import { isScalarValue } from './Scalar.js'; |
|
import { toJS } from './toJS.js'; |
|
|
|
class YAMLSeq extends Collection { |
|
constructor(schema) { |
|
super(SEQ, schema); |
|
this.items = []; |
|
} |
|
static get tagName() { |
|
return 'tag:yaml.org,2002:seq'; |
|
} |
|
add(value) { |
|
this.items.push(value); |
|
} |
|
/** |
|
* Removes a value from the collection. |
|
* |
|
* `key` must contain a representation of an integer for this to succeed. |
|
* It may be wrapped in a `Scalar`. |
|
* |
|
* @returns `true` if the item was found and removed. |
|
*/ |
|
delete(key) { |
|
const idx = asItemIndex(key); |
|
if (typeof idx !== 'number') |
|
return false; |
|
const del = this.items.splice(idx, 1); |
|
return del.length > 0; |
|
} |
|
get(key, keepScalar) { |
|
const idx = asItemIndex(key); |
|
if (typeof idx !== 'number') |
|
return undefined; |
|
const it = this.items[idx]; |
|
return !keepScalar && isScalar(it) ? it.value : it; |
|
} |
|
/** |
|
* Checks if the collection includes a value with the key `key`. |
|
* |
|
* `key` must contain a representation of an integer for this to succeed. |
|
* It may be wrapped in a `Scalar`. |
|
*/ |
|
has(key) { |
|
const idx = asItemIndex(key); |
|
return typeof idx === 'number' && idx < this.items.length; |
|
} |
|
/** |
|
* Sets a value in this collection. For `!!set`, `value` needs to be a |
|
* boolean to add/remove the item from the set. |
|
* |
|
* If `key` does not contain a representation of an integer, this will throw. |
|
* It may be wrapped in a `Scalar`. |
|
*/ |
|
set(key, value) { |
|
const idx = asItemIndex(key); |
|
if (typeof idx !== 'number') |
|
throw new Error(`Expected a valid index, not ${key}.`); |
|
const prev = this.items[idx]; |
|
if (isScalar(prev) && isScalarValue(value)) |
|
prev.value = value; |
|
else |
|
this.items[idx] = value; |
|
} |
|
toJSON(_, ctx) { |
|
const seq = []; |
|
if (ctx?.onCreate) |
|
ctx.onCreate(seq); |
|
let i = 0; |
|
for (const item of this.items) |
|
seq.push(toJS(item, String(i++), ctx)); |
|
return seq; |
|
} |
|
toString(ctx, onComment, onChompKeep) { |
|
if (!ctx) |
|
return JSON.stringify(this); |
|
return stringifyCollection(this, ctx, { |
|
blockItemPrefix: '- ', |
|
flowChars: { start: '[', end: ']' }, |
|
itemIndent: (ctx.indent || '') + ' ', |
|
onChompKeep, |
|
onComment |
|
}); |
|
} |
|
} |
|
function asItemIndex(key) { |
|
let idx = isScalar(key) ? key.value : key; |
|
if (idx && typeof idx === 'string') |
|
idx = Number(idx); |
|
return typeof idx === 'number' && Number.isInteger(idx) && idx >= 0 |
|
? idx |
|
: null; |
|
} |
|
|
|
export { YAMLSeq };
|
|
|