Skip to content

Commit

Permalink
a few minor touchups
Browse files Browse the repository at this point in the history
 - biome format
 - pack's param is now named `e` instead of `entry` to be more usable in inlay hints
 - fetch wrapper is now actually functional
  • Loading branch information
oofdere committed Aug 16, 2024
1 parent b5eba3c commit 47ac181
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 38 deletions.
12 changes: 6 additions & 6 deletions coins.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Enum, match } from "./index";

type Coins = {
Penny: 1,
Nickel: 5,
Dime: 10,
Quarter: 25,
}
const Coins = Enum<Coins>()
Penny: 1;
Nickel: 5;
Dime: 10;
Quarter: 25;
};
const Coins = Enum<Coins>();

// you have to specify a value, but the type checker won't let you enter anything other than the preset value
const penny = Coins("Penny", 1);
Expand Down
22 changes: 12 additions & 10 deletions src/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@ export type Enum<E> = { [K in keyof E]: [K, E[K]] }[keyof E];
// "-?" removes any optional parameters, making all cases required
export type Arms<E> =
| {
[K in keyof E]-?: (x: E[K]) => unknown;
}
[K in keyof E]-?: (x: E[K]) => unknown;
}
| ({
[L in keyof E]?: (x: E[L]) => unknown;
} & {
_: (x: Enum<E>[1]) => unknown;
});
[L in keyof E]?: (x: E[L]) => unknown;
} & {
_: (x: Enum<E>[1]) => unknown;
});

// this is a generic way to create enum instances, but the Enum() factory function is preferred
export const pack = <E>(...entry: Enum<E>) => entry as E;
export const pack = <E>(...e: Enum<E>) => e as E;

export const Enum =
<E>() =>
(...entry: Enum<E>) =>
entry as unknown as E;
(...e: Enum<E>) =>
e as unknown as E;

export const match = <E, Fn extends Arms<E>>(pattern: E, arms: Fn) =>
// biome-ignore lint/suspicious/noExplicitAny: return type is handled externally
(((arms as any)[(pattern as any[])[0]] as any) || (arms as any)._)((pattern as any)[1] as unknown,) as ReturnType<Exclude<(typeof arms)[keyof typeof arms], undefined>>;
(((arms as any)[(pattern as any[])[0]] as any) || (arms as any)._)(
(pattern as any)[1] as unknown,
) as ReturnType<Exclude<(typeof arms)[keyof typeof arms], undefined>>;
53 changes: 34 additions & 19 deletions src/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,51 @@
import { EnumChecked, match, pack, type Enum } from "./enum";
import { Enum, match, pack } from "./enum";
import { Err, Ok, type Result } from "./result";

type FetchErr = {
AbortError: DOMException;
NotAllowedError: DOMException;
TypeError: TypeError;
OtherError: unknown;
Redirect: Response;
ClientError: Response;
ServerError: Response;
};

async function f(
const todo = (x?: unknown) => console.trace("todo!", x);
const FetchErr = Enum<FetchErr>();

export async function f(
input: string | URL | globalThis.Request,
init?: RequestInit,
): Promise<Result<Response, FetchErr>> {
try {
return Ok(await fetch(input, init));
const res = await fetch(input, init);

if (res.ok) {
return Ok(res);
}

if (res.status >= 300 && res.status < 400) {
return Err(FetchErr("Redirect", res));
}

if (res.status >= 400 && res.status < 500) {
return Err(FetchErr("ClientError", res));
}

if (res.status >= 500) {
return Err(FetchErr("ServerError", res));
}

return Ok(res);
} catch (e) {
if (e instanceof TypeError) {
return Err(FetchErr("TypeError", e));
}

if (e instanceof DOMException) {
return Err(pack("AbortError", e));
return Err(FetchErr("AbortError", e));
}
return Err(pack("OtherError", e)); //=>

throw e;
}
}

match(await f("i"), {
//=>
Ok: (x) => x, //=>
Err: (x) =>
match(x, {
AbortError(x) {
//=>
console.log("wtaf");
},
_: (x) => x, //=>
}), //=>
});
6 changes: 3 additions & 3 deletions vanilla.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
enum ColorEnum {
Red,
Green,
Blue,
Red = 0,
Green = 1,
Blue = 2,
}

const red = ColorEnum.Red;
Expand Down

0 comments on commit 47ac181

Please sign in to comment.