Last active
August 2, 2024 13:29
-
-
Save toky-nomena/4ba8e42c249e2e0464bbf5f01d1e893f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const matcher = <Input, Output>(value: Input) => { | |
type Result = (value: Input) => Output; | |
type Expression = (value: Input) => boolean; | |
interface MatchCases { | |
expression: Expression; | |
result: Result; | |
} | |
const cases: MatchCases[] = []; | |
let defaultCase: Result = () => { | |
throw new Error("No default case provided"); | |
}; | |
function run(): Output { | |
for (const { expression, result } of cases) { | |
if (expression(value)) { | |
return result(value); | |
} | |
} | |
return defaultCase(value); | |
} | |
function setDefault(result: Result) { | |
defaultCase = result; | |
return run(); | |
} | |
function addCase(expression: Expression, result: Result) { | |
cases.push({ expression, result }); | |
return { case: addCase, default: setDefault }; | |
} | |
return { case: addCase }; | |
}; | |
export const asyncMatcher = <Input, Output>(value: Input) => { | |
type Result = (value: Input) => Output | Promise<Output>; | |
type Expression = (value: Input) => boolean | Promise<boolean>; | |
interface MatchCases { | |
expression: Expression; | |
result: Result; | |
} | |
const cases: MatchCases[] = []; | |
let defaultCase: Result = () => { | |
throw new Error("No default case provided"); | |
}; | |
async function run() { | |
for (const { expression, result } of cases) { | |
if (await expression(value)) { | |
return await result(value); | |
} | |
} | |
return defaultCase(value); | |
} | |
function setDefault(result: Result) { | |
defaultCase = result; | |
return run(); | |
} | |
function addCase(expression: Expression, result: Result) { | |
cases.push({ expression, result }); | |
return { case: addCase, default: setDefault }; | |
} | |
return { case: addCase }; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment