mirror of
https://github.com/voson-wang/toon.git
synced 2026-01-29 23:34:10 +08:00
90 lines
2.0 KiB
TypeScript
90 lines
2.0 KiB
TypeScript
import type { JsonPrimitive } from '../types'
|
|
import { COMMA, DEFAULT_DELIMITER, DOUBLE_QUOTE, NULL_LITERAL } from '../constants'
|
|
import { escapeString } from '../shared/string-utils'
|
|
import { isSafeUnquoted, isValidUnquotedKey } from '../shared/validation'
|
|
|
|
// #region Primitive encoding
|
|
|
|
export function encodePrimitive(value: JsonPrimitive, delimiter?: string): string {
|
|
if (value === null) {
|
|
return NULL_LITERAL
|
|
}
|
|
|
|
if (typeof value === 'boolean') {
|
|
return String(value)
|
|
}
|
|
|
|
if (typeof value === 'number') {
|
|
return String(value)
|
|
}
|
|
|
|
return encodeStringLiteral(value, delimiter)
|
|
}
|
|
|
|
export function encodeStringLiteral(value: string, delimiter: string = COMMA): string {
|
|
if (isSafeUnquoted(value, delimiter)) {
|
|
return value
|
|
}
|
|
|
|
return `${DOUBLE_QUOTE}${escapeString(value)}${DOUBLE_QUOTE}`
|
|
}
|
|
|
|
// #endregion
|
|
|
|
// #region Key encoding
|
|
|
|
export function encodeKey(key: string): string {
|
|
if (isValidUnquotedKey(key)) {
|
|
return key
|
|
}
|
|
|
|
return `${DOUBLE_QUOTE}${escapeString(key)}${DOUBLE_QUOTE}`
|
|
}
|
|
|
|
// #endregion
|
|
|
|
// #region Value joining
|
|
|
|
export function encodeAndJoinPrimitives(values: readonly JsonPrimitive[], delimiter: string = COMMA): string {
|
|
return values.map(v => encodePrimitive(v, delimiter)).join(delimiter)
|
|
}
|
|
|
|
// #endregion
|
|
|
|
// #region Header formatters
|
|
|
|
export function formatHeader(
|
|
length: number,
|
|
options?: {
|
|
key?: string
|
|
fields?: readonly string[]
|
|
delimiter?: string
|
|
lengthMarker?: '#' | false
|
|
},
|
|
): string {
|
|
const key = options?.key
|
|
const fields = options?.fields
|
|
const delimiter = options?.delimiter ?? COMMA
|
|
const lengthMarker = options?.lengthMarker ?? false
|
|
|
|
let header = ''
|
|
|
|
if (key) {
|
|
header += encodeKey(key)
|
|
}
|
|
|
|
// Only include delimiter if it's not the default (comma)
|
|
header += `[${lengthMarker || ''}${length}${delimiter !== DEFAULT_DELIMITER ? delimiter : ''}]`
|
|
|
|
if (fields) {
|
|
const quotedFields = fields.map(f => encodeKey(f))
|
|
header += `{${quotedFields.join(delimiter)}}`
|
|
}
|
|
|
|
header += ':'
|
|
|
|
return header
|
|
}
|
|
|
|
// #endregion
|