Begin re-write in proper functional style

This commit is contained in:
Eric Rumsey 2025-05-23 17:37:51 -05:00
parent 9c09560b73
commit e897ca7848

View File

@ -1,47 +1,63 @@
import { tryCatch } from '@maxmorozoff/try-catch-tuple';
import type { CursorPosition } from '../util/terminal';
import { type CursorPos } from 'node:readline'
const setInitialEnd = (pos: {
origin: CursorPosition;
end?: CursorPosition;
lines?: number;
}) => {
if (!pos.end || !pos.lines)
throw TypeError("One of 'end' or 'lines' must be set");
if (Object.keys(pos).includes('end') || Object.keys(pos).includes('end'))
throw TypeError("Cannot set both 'end' and 'lines'");
if (pos.end) return pos.end;
return {
row: pos.origin.row + pos.lines,
col: pos.origin.col,
};
};
// Cursor stuffs
interface CursorPosX {
readonly _tag: 'X'
readonly value: number
}
export const createCanvas = (
pos: { origin: CursorPosition; end?: CursorPosition; lines?: number },
paint: () => Promise<number>,
cleanup?: () => Promise<number>
) => {
let currentOrigin = pos.origin;
interface CursorPosY {
readonly _tag: 'Y'
readonly value: number
}
let currentEnd;
const [endVal, endError] = tryCatch(() => setInitialEnd(pos));
if (endError) throw endError;
currentEnd = endVal;
const cursorPosX = (x: number): CursorPosX => ({_tag: 'X', value: x})
paint();
//
// Paint function
//
// Restore origin position
// Clear to cursor end position
//
// API
// ---
// get origin
// get end
// move end
// get line count
// clear canvas
return [1];
};
const cursorPosY = (x: number): CursorPosY => ({_tag: 'Y', value: x})
type IsCursorPos =
(x: 'X' | 'Y') => (y: CursorPosX | CursorPosY) => boolean
const isCursorPos: IsCursorPos = x => y => y._tag === x
// Tagged types
interface CanvasOrigin {
readonly _tag: 'Origin'
readonly value: CursorPos
}
interface CanvasEnd {
readonly _tag: 'End'
readonly value: CursorPos
}
// Canvas type using tagged positions
type Canvas = {
origin: CanvasOrigin,
end: CanvasEnd,
}
// Cursor Position
// const cursorPos: CursorPos = ()
// Constructor helpers
const origin = (pos: CursorPos): CanvasOrigin => ({
_tag: 'Origin',
value: pos,
})
const end = (pos: CursorPos): CanvasEnd => ({
_tag: 'End',
value: pos,
})
// Curried canvas creator with type safety
const canvas =
(origin: CanvasOrigin) => (end: CanvasEnd): Canvas => ({
origin,
end,
})
// Usage with proper type safety
const myCanvas = canvas(origin({rows: 3, cols: 1}))(
end({rows: 8, cols: 1}),
)