Metch is a TypeScript package that provides utility functions for branching and conditional execution based on patterns. It allows you to define multiple branches, evaluate an item against these branches, and execute the corresponding callbacks based on the matching branch.
You can install Metch using npm or yarn:
npm install metch
or
yarn add metch
To use Metch in your TypeScript project, import the desired functions from the package:
import { metch, metchReturn, DefaultBranch } from 'metch-case';
The metch
function evaluates an item against a set of branches and executes the callback associated with the first matching branch. It follows a specific order of evaluation where the first matching branch is executed, and subsequent branches are ignored.
metch<T>(item: T, branches: MatchBranches<T>, defaultBranch?: MetchBranchCallback<T>): void | Promise<void>
item
: The item to be evaluated against the branches.branches
: An array ofMatchBranch
objects. EachMatchBranch
is an array of 2 items:-BranchJudge
: will evaluate the item given. ajudge
can be a boolean, or a value of the same type as item, or a function that returns a booleanBranchCallback
: will execute if the judge allows it. Can be both async and sync.
defaultBranch
: Optional default branch if all other branches not matched.
import {metch, DefaultBranch} from 'metch-case';
import fs from "fs/promises"
let filePath: string | undefined = 'notValid.txt';
await metch(filePath, [
[undefined, async (file) => {
console.log(await fs.readFile("undefined.txt", "utf-8"));
}],
['animal.txt', async (file) => {
console.log(await fs.readFile(file!, "utf-8"))
}],
[path => path!.includes('.txt'), async (file) => {
console.log(await fs.readFile('data.txt', "utf-8"));
}]
], async (item) => {
// Optional Default branch
console.log(await fs.readFile('default.txt', 'utf-8'))
})
The metchReturn
function evaluates an item against a set of branches, executes the callback associated with the first matching branch, and returns a value. It follows the same evaluation order as metch
, where the first matching branch is executed and subsequent branches are ignored.
If none of the branches match, the defaultBranch callback is executed.
metchReturn<T, U>(item: T, branches: MatchReturnBranches<T, U>, defaultBranch: MatchReturnDefaultbranch<T, U>): U | Promise<U>
item
: The item to be evaluated against the branches.branches
: An array ofMatchReturnBranch
objects. EachMatchReturnBranch
consists of a branch judge or value, and a callback function to be executed if the judge or value matches the item.defaultBranch
: The callback function to be executed if none of the branches match.
import { metchReturn } from 'metch-case';
import fs from "fs/promises"
let filePath: string | undefined = 'animal.txt';
const fileData = await metchReturn(filePath, [
[undefined, async (file) => {
return await fs.readFile("undefined.txt", "utf-8");
}],
['animal.txt', async (file) => {
return await fs.readFile(file!, "utf-8");
}],
[path => path!.includes('.txt'), async (file) => {
return await fs.readFile('data.txt', "utf-8");
}],
], async (file) => {
// Default Branch
return await fs.readFile('default.txt', 'utf-8')
});
console.log(fileData);
Each branch inside metch()
or metchReturn()
has a judge
. The item will be evaluated using this judge
. If the judge
allows it, then the callback inside that branch will be executed, and other branches will be ignored.
A judge<T>
(Where T
is the type of the item
given) can be one of the following :-
boolean
(item: T) => boolean | undefined
T
Query<T>
Callback will be executed if judge
is true
.
let filePath: string | undefined = 'animal.txt';
const fileData = await metchReturn(filePath, [
[true, async (file) => {
// Will always be executed and ignore other branches
return await fs.readFile("always.txt", "utf-8");
}]
], async (file) => {
// Default Branch
return await fs.readFile('default.txt', 'utf-8')
});
Callback will be executed if the result of the function is true
.
let filePath: string = 'animal.txt';
const fileData = await metchReturn(filePath, [
[(file) => file.endsWith('.txt'), async (file) => {
return await fs.readFile(file, "utf-8");
}]
], async (file) => {
// Default Branch
return await fs.readFile('default.txt', 'utf-8')
});
Callback will be executed if the judge
is strictly equal to item
. In this case judge
must be the same type as item
.
let filePath: string | undefined = 'animal.txt';
const fileData = await metchReturn(filePath, [
[undefined, async () => {
return await fs.readFile('undefined.txt', 'utf-8')
}]
[(file) => file!.endsWith('.txt'), async (file) => {
return await fs.readFile(file, 'utf-8');
}]
], async (file) => {
// Default Branch
return await fs.readFile('default.txt', 'utf-8')
});
Act as AND
/ OR
operator for a branch's judge.
const branches: MetchBranches<any> = [
[Query.Or<any>(undefined, null, 1, (path: any) => typeof path !== 'string'), () => {
console.log('value is not a valid string')
}],
[Query.And((path: any) => typeof path === 'string', 'animal'), (item) => {
console.log('value is a string and animal')
}],
];
await metch('animal' as any, branches, (item) => {
console.log('default branch')
});
It is recommended to pass the item
's data type when using the Query
.
let item: string | undefined = 'hello world';
Query.And<string | undefined>(...);
Query.Or<string | null>(...);