Compare commits
2 Commits
300a538314
...
baab2e75d9
| Author | SHA1 | Date | |
|---|---|---|---|
| baab2e75d9 | |||
| 4f1847efa8 |
@ -1,4 +1,6 @@
|
|||||||
import { type CursorPos } from 'node:readline'
|
import { type CursorPos } from 'node:readline'
|
||||||
|
import { type Either, fold, type Left, left, right } from '../util/basic/either'
|
||||||
|
import { PaintCursorError } from './errors'
|
||||||
|
|
||||||
// Cursor stuffs
|
// Cursor stuffs
|
||||||
interface CursorPosX {
|
interface CursorPosX {
|
||||||
@ -11,14 +13,35 @@ interface CursorPosY {
|
|||||||
readonly value: number
|
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 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<CursorPos, Error>
|
||||||
|
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
|
// Tagged types
|
||||||
interface CanvasOrigin {
|
interface CanvasOrigin {
|
||||||
readonly _tag: 'Origin'
|
readonly _tag: 'Origin'
|
||||||
@ -30,15 +53,23 @@ interface CanvasEnd {
|
|||||||
readonly value: CursorPos
|
readonly value: CursorPos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CanvasOriginConstructor = (x: SafeCursorPos) => Either<CanvasOrigin, E>
|
||||||
|
const canvasOrigin = (x: CursorPos): CanvasOrigin => ({
|
||||||
|
_tag: 'Origin',
|
||||||
|
value: x,
|
||||||
|
})
|
||||||
|
|
||||||
|
const canvasEnd = (x: CursorPos): CanvasEnd => ({
|
||||||
|
_tag: 'End',
|
||||||
|
value: x,
|
||||||
|
})
|
||||||
|
|
||||||
// Canvas type using tagged positions
|
// Canvas type using tagged positions
|
||||||
type Canvas = {
|
type Canvas = {
|
||||||
origin: CanvasOrigin,
|
origin: CanvasOrigin,
|
||||||
end: CanvasEnd,
|
end: CanvasEnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cursor Position
|
|
||||||
// const cursorPos: CursorPos = ()
|
|
||||||
|
|
||||||
// Constructor helpers
|
// Constructor helpers
|
||||||
const origin = (pos: CursorPos): CanvasOrigin => ({
|
const origin = (pos: CursorPos): CanvasOrigin => ({
|
||||||
_tag: 'Origin',
|
_tag: 'Origin',
|
||||||
@ -51,11 +82,10 @@ const end = (pos: CursorPos): CanvasEnd => ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Curried canvas creator with type safety
|
// Curried canvas creator with type safety
|
||||||
const canvas =
|
const canvas = (origin: CanvasOrigin) => (end: CanvasEnd): Canvas => ({
|
||||||
(origin: CanvasOrigin) => (end: CanvasEnd): Canvas => ({
|
origin,
|
||||||
origin,
|
end,
|
||||||
end,
|
})
|
||||||
})
|
|
||||||
|
|
||||||
// Usage with proper type safety
|
// Usage with proper type safety
|
||||||
const myCanvas = canvas(origin({rows: 3, cols: 1}))(
|
const myCanvas = canvas(origin({rows: 3, cols: 1}))(
|
||||||
|
|||||||
12
src/lib/painter/errors.ts
Normal file
12
src/lib/painter/errors.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export class PaintCursorError extends Error {
|
||||||
|
cursorX
|
||||||
|
cursorY
|
||||||
|
|
||||||
|
constructor(message: string, {x, y}: {x: unknown, y: unknown}) {
|
||||||
|
super(message)
|
||||||
|
|
||||||
|
this.name = this.constructor.name
|
||||||
|
this.cursorX = !x ? 'No data' : x
|
||||||
|
this.cursorY = !y ? 'No data' : y
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user