diff --git a/src/lib/painter/canvas.ts b/src/lib/painter/canvas.ts index 7df02bf..6695985 100644 --- a/src/lib/painter/canvas.ts +++ b/src/lib/painter/canvas.ts @@ -1,4 +1,6 @@ import { type CursorPos } from 'node:readline' +import { type Either, fold, type Left, left, right } from '../util/basic/either' +import { PaintCursorError } from './errors' // Cursor stuffs interface CursorPosX { @@ -11,14 +13,35 @@ interface CursorPosY { readonly value: number } -const cursorPosX = (x: number): CursorPosX => ({_tag: 'X', value: x}) +type CursorPosVal = (str: 'X' | 'Y') => (x: number) => CursorPosX | CursorPosY +const cursorPosVal: CursorPosVal = str => x => ({_tag: str, value: x}) -const cursorPosY = (x: number): CursorPosY => ({_tag: 'Y', value: x}) - -type IsCursorPos = - (x: 'X' | 'Y') => (y: CursorPosX | CursorPosY) => boolean +type IsCursorPos = (x: 'X' | 'Y') => (y: CursorPosX | CursorPosY) => boolean const isCursorPos: IsCursorPos = x => y => y._tag === x +const cursorPos = (x: number) => (y: number): CursorPos => ({rows: x, cols: y}) + +// Cursor Position +type SafeCursorPos = + (x: CursorPosX | CursorPosY) => + (y: CursorPosX | CursorPosY) => Either +const safeCursorPos: SafeCursorPos = (x) => y => { + return isCursorPos('X')(x) && isCursorPos('Y')(y) + ? right(cursorPos(x.value)(y.value)) + : isCursorPos('Y')(x) && isCursorPos('X')(y) + ? right(cursorPos(y.value)(x.value)) + : left( + new PaintCursorError( + `Both arguments provided were of the same axis, or otherwise invalid.`, + {x, y}, + ), + ) +} + +console.log( + safeCursorPos(cursorPosVal('X')(5))(cursorPosVal('X')(7)), +) + // Tagged types interface CanvasOrigin { readonly _tag: 'Origin' @@ -30,15 +53,23 @@ interface CanvasEnd { readonly value: CursorPos } +type CanvasOriginConstructor = (x: SafeCursorPos) => Either +const canvasOrigin = (x: CursorPos): CanvasOrigin => ({ + _tag: 'Origin', + value: x, +}) + +const canvasEnd = (x: CursorPos): CanvasEnd => ({ + _tag: 'End', + value: x, +}) + // 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', @@ -51,11 +82,10 @@ const end = (pos: CursorPos): CanvasEnd => ({ }) // Curried canvas creator with type safety -const canvas = - (origin: CanvasOrigin) => (end: CanvasEnd): Canvas => ({ - origin, - end, - }) +const canvas = (origin: CanvasOrigin) => (end: CanvasEnd): Canvas => ({ + origin, + end, +}) // Usage with proper type safety const myCanvas = canvas(origin({rows: 3, cols: 1}))(