UNPKG

@randsum/notation

Version:

Dice notation parser and types for the @randsum ecosystem

66 lines (54 loc) 2.37 kB
import type { ComparisonOptions, ReplaceOptions } from '../types' import { formatComparisonDescription, formatComparisonNotation } from '../comparison' import { type NotationSchema, defineNotationSchema } from '../schema' const replacePattern = /[Vv]\{((?:>=|<=|>|<)?\d+=\d+(?:,(?:>=|<=|>|<)?\d+=\d+)*)\}/ export const replaceSchema: NotationSchema<ReplaceOptions | ReplaceOptions[]> = defineNotationSchema<ReplaceOptions | ReplaceOptions[]>({ name: 'replace', priority: 30, pattern: replacePattern, parse: notation => { const match = replacePattern.exec(notation) if (!match) return {} const content = match[1] if (!content) return {} const parts = content.split(',').map(s => s.trim()) const replacements = parts.map(part => { const fromToMatch = /^((?:>=|<=|>|<)?\d+)=(\d+)$/.exec(part) if (!fromToMatch?.[1] || !fromToMatch[2]) return { from: 0, to: 0 } const [, fromStr, toStr] = fromToMatch const from: number | ComparisonOptions = fromStr.startsWith('>=') ? { greaterThanOrEqual: Number(fromStr.slice(2)) } : fromStr.startsWith('<=') ? { lessThanOrEqual: Number(fromStr.slice(2)) } : fromStr.startsWith('>') ? { greaterThan: Number(fromStr.slice(1)) } : fromStr.startsWith('<') ? { lessThan: Number(fromStr.slice(1)) } : Number(fromStr) return { from, to: Number(toStr) } }) return { replace: replacements } }, toNotation: options => { const rules = Array.isArray(options) ? options : [options] const notations = rules.map(({ from, to }) => { if (typeof from === 'object') { const comparisons = formatComparisonNotation(from) return comparisons.map(comp => `${comp}=${to}`).join(',') } return `${from}=${to}` }) return notations.length ? `V{${notations.join(',')}}` : undefined }, toDescription: options => { const rules = Array.isArray(options) ? options : [options] return rules.map(({ from, to }) => { if (typeof from === 'object') { const comparisons = formatComparisonDescription(from) return `Replace ${comparisons.join(' and ')} with ${to}` } return `Replace ${from} with ${to}` }) } })