UNPKG

@randsum/notation

Version:

Dice notation parser and types for the @randsum ecosystem

51 lines (40 loc) 1.32 kB
import type { ModifierOptions } from '../types' import { defineNotationSchema } from '../schema' type ArithmeticKey = 'plus' | 'minus' interface ArithmeticNotationConfig { name: ArithmeticKey priority: number operator: '+' | '-' verb: string } export function createArithmeticNotation( config: ArithmeticNotationConfig ): ReturnType<typeof defineNotationSchema<number>> { const { name, priority, operator, verb } = config const escapedOperator = operator === '+' ? '\\+' : '-' const pattern = new RegExp(`${escapedOperator}(\\d+)`) const globalPattern = new RegExp(`${escapedOperator}(\\d+)`, 'g') return defineNotationSchema<number>({ name, priority, pattern, parse: notation => { const matches = Array.from(notation.matchAll(globalPattern)) if (matches.length === 0) return {} const total = matches.reduce((sum, match) => sum + Number(match[1]), 0) const result: Pick<ModifierOptions, ArithmeticKey> = { [name]: total } as Pick<ModifierOptions, ArithmeticKey> return result }, toNotation: options => { if (name === 'plus' && options < 0) { return `-${Math.abs(options)}` } return `${operator}${options}` }, toDescription: options => { return [`${verb} ${options}`] } }) }