Skip to content

Commit

Permalink
feat(extract): add pattern matching for option
Browse files Browse the repository at this point in the history
  • Loading branch information
TomokiMiyauci committed Jul 4, 2023
1 parent 034fbba commit 957350f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 2 deletions.
33 changes: 33 additions & 0 deletions operators/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,36 @@ export function expect<T>(

throw new error(msg);
}

/** {@link Option} matcher. */
export interface Matcher<T, U> {
/** Match on `Some`. */
Some: (value: T) => U;

/** Match on `None`. */
None: () => U;
}

/** Pattern matching for {@link option}. Match on {@link matcher.Some} if `Some`, otherwise match on {@link matcher.None}.
*
* @example
* ```ts
* import { None, type Option } from "https://deno.land/x/optio/spec.ts";
* import { match } from "https://deno.land/x/optio/operators/extract.ts";
*
* declare const option: Option<number>;
*
* match(option, {
* Some: (value) => value,
* None: () => 500,
* });
* ```
*/
export function match<T, U>(
option: Option<T>,
matcher: Readonly<Matcher<T, U>>,
): U {
if (isSome(option)) return matcher.Some(option.get);

return matcher.None();
}
25 changes: 23 additions & 2 deletions operators/extract_test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright © 2023 Tomoki Miyauchi. All rights reserved. MIT license.
// This module is browser compatible.

import { expect, unwrap, unwrapOr, unwrapOrElse } from "./extract.ts";
import { expect, match, unwrap, unwrapOr, unwrapOrElse } from "./extract.ts";
import { None, Some } from "../spec.ts";
import {
assertEquals,
assertSpyCallArgs,
assertSpyCalls,
assertThrows,
describe,
Expand Down Expand Up @@ -61,3 +61,24 @@ describe("expect", () => {
assertThrows(() => expect(None, message, RangeError), RangeError, message);
});
});

describe("match", () => {
it("should call Some if Some", () => {
const s = spy(() => 1);
const n = spy(() => 2);

assertEquals(match(Some.of(0), { Some: s, None: n }), 1);
assertSpyCalls(s, 1);
assertSpyCalls(n, 0);
assertSpyCallArgs(s, 0, [0]);
});

it("should call None if None", () => {
const s = spy(() => 1);
const n = spy(() => 2);

assertEquals(match(None, { Some: s, None: n }), 2);
assertSpyCalls(s, 0);
assertSpyCalls(n, 1);
});
});

0 comments on commit 957350f

Please sign in to comment.