UNPKG

@gulujs/toml

Version:

TOML parser and serializer

121 lines (120 loc) 4.53 kB
import { ObjectPath, QuoteStyleKeyPath } from '@gulujs/object-path'; import { tryStringifyKeyValue } from './types/index.js'; import { SchemaType } from './schema.js'; import { DatetimeConverter, FloatConverter, IntegerConverter } from '../converter/index.js'; export class SimpleModeSerializer { constructor(obj, options) { this.obj = obj; this.lines = []; this.objectPath = new ObjectPath({ keyPath: new QuoteStyleKeyPath(options) }); this.newline = options?.newline || '\n'; this.treatFunctionAsObject = options?.treatFunctionAsObject; this.integerConverter = options?.integerConverter || new IntegerConverter(); this.floatConverter = options?.floatConverter || new FloatConverter(); this.datetimeConverter = options?.datetimeConverter || new DatetimeConverter(); this.options = { simpleMode: true, topLevel: true, objectPath: this.objectPath, newline: this.newline, treatFunctionAsObject: this.treatFunctionAsObject, preferQuote: options?.preferQuote || "'", preferOneLineString: options?.preferOneLineString, escapeTabChar: options?.escapeTabChar, globalStringSplitter: options?.globalStringSplitter, integerConverter: this.integerConverter, floatConverter: this.floatConverter, datetimeConverter: this.datetimeConverter }; } serialize() { this.serializeInSimpleMode(this.obj, []); return this.lines.join(this.newline); } serializeInSimpleMode(obj, path, isArrayOfTables = false) { if (path.length > 0) { if (this.lines.length > 0) { this.lines.push(''); } this.lines.push(`${isArrayOfTables ? '[[' : '['}${this.objectPath.keyPath.stringify(path)}${isArrayOfTables ? ']]' : ']'}`); } const numOfLines = this.lines.length; const keys = Object.keys(obj); const restKeys = []; for (const key of keys) { const value = obj[key]; const valuePath = [key]; const schema = { type: SchemaType.Any, key: valuePath }; if (tryStringifyKeyValue(value, schema, this.options, [valuePath], this.lines)) { continue; } if (Array.isArray(value) && !this.isArrayOfTables(value)) { tryStringifyKeyValue(value, { type: SchemaType.Array, key: valuePath, items: SchemaType.Any }, this.options, [valuePath], this.lines); continue; } restKeys.push(key); } if (numOfLines === this.lines.length && numOfLines > 0 && restKeys.length > 0 && !isArrayOfTables) { this.lines.pop(); this.lines.pop(); } for (const key of restKeys) { const value = obj[key]; const valuePath = [...path, key]; if (!Array.isArray(value)) { this.serializeInSimpleMode(value, valuePath); continue; } for (let i = 0; i < value.length; i++) { this.serializeInSimpleMode(value[i], valuePath, true); } } } isArrayOfTables(value) { if (value.length === 0) { return false; } for (let i = 0; i < value.length; i++) { switch (typeof value[i]) { case 'string': case 'number': case 'bigint': case 'boolean': case 'symbol': case 'undefined': return false; case 'function': if (this.treatFunctionAsObject) { continue; } return false; default: } if (this.integerConverter.isJsValue(value[i])) { return false; } if (this.floatConverter.isJsValue(value[i])) { return false; } if (value[i] === null) { return false; } if (this.datetimeConverter.isJsValue(value[i])) { return false; } if (Array.isArray(value[i])) { return false; } } return true; } }