mirror of
https://github.com/voson-wang/toon.git
synced 2026-01-29 23:34:10 +08:00
refactor: decoding source files
This commit is contained in:
97
src/decode/validation.ts
Normal file
97
src/decode/validation.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import type { ArrayHeaderInfo, Delimiter, Depth, ResolvedDecodeOptions } from '../types'
|
||||
import type { LineCursor } from './scanner'
|
||||
import { COLON, LIST_ITEM_PREFIX } from '../constants'
|
||||
|
||||
/**
|
||||
* Asserts that the actual count matches the expected count in strict mode.
|
||||
*
|
||||
* @param actual The actual count
|
||||
* @param expected The expected count
|
||||
* @param itemType The type of items being counted (e.g., 'list array items', 'tabular rows')
|
||||
* @param options Decode options
|
||||
* @throws RangeError if counts don't match in strict mode
|
||||
*/
|
||||
export function assertExpectedCount(
|
||||
actual: number,
|
||||
expected: number,
|
||||
itemType: string,
|
||||
options: ResolvedDecodeOptions,
|
||||
): void {
|
||||
if (options.strict && actual !== expected) {
|
||||
throw new RangeError(`Expected ${expected} ${itemType}, but got ${actual}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that there are no extra list items beyond the expected count.
|
||||
*
|
||||
* @param cursor The line cursor
|
||||
* @param itemDepth The expected depth of items
|
||||
* @param expectedCount The expected number of items
|
||||
* @throws RangeError if extra items are found
|
||||
*/
|
||||
export function validateNoExtraListItems(
|
||||
cursor: LineCursor,
|
||||
itemDepth: Depth,
|
||||
expectedCount: number,
|
||||
): void {
|
||||
if (cursor.atEnd())
|
||||
return
|
||||
|
||||
const nextLine = cursor.peek()
|
||||
if (nextLine && nextLine.depth === itemDepth && nextLine.content.startsWith(LIST_ITEM_PREFIX)) {
|
||||
throw new RangeError(`Expected ${expectedCount} list array items, but found more`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a line represents a data row (as opposed to a key-value pair) in a tabular array.
|
||||
*
|
||||
* @param content The line content
|
||||
* @param delimiter The delimiter used in the table
|
||||
* @returns true if the line is a data row, false if it's a key-value pair
|
||||
*/
|
||||
export function isDataRow(content: string, delimiter: Delimiter): boolean {
|
||||
const colonPos = content.indexOf(COLON)
|
||||
const delimiterPos = content.indexOf(delimiter)
|
||||
|
||||
// No colon = definitely a data row
|
||||
if (colonPos === -1) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Has delimiter and it comes before colon = data row
|
||||
if (delimiterPos !== -1 && delimiterPos < colonPos) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Colon before delimiter or no delimiter = key-value pair
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that there are no extra tabular rows beyond the expected count.
|
||||
*
|
||||
* @param cursor The line cursor
|
||||
* @param rowDepth The expected depth of rows
|
||||
* @param header The array header info containing length and delimiter
|
||||
* @throws RangeError if extra rows are found
|
||||
*/
|
||||
export function validateNoExtraTabularRows(
|
||||
cursor: LineCursor,
|
||||
rowDepth: Depth,
|
||||
header: ArrayHeaderInfo,
|
||||
): void {
|
||||
if (cursor.atEnd())
|
||||
return
|
||||
|
||||
const nextLine = cursor.peek()
|
||||
if (
|
||||
nextLine
|
||||
&& nextLine.depth === rowDepth
|
||||
&& !nextLine.content.startsWith(LIST_ITEM_PREFIX)
|
||||
&& isDataRow(nextLine.content, header.delimiter)
|
||||
) {
|
||||
throw new RangeError(`Expected ${header.length} tabular rows, but found more`)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user