Created
May 8, 2025 10:39
-
-
Save luoling8192/72ac6bb766a539b02bfdab8b04aa2074 to your computer and use it in GitHub Desktop.
Telegram Search Monad
This file contains hidden or 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
| import { describe, expect, it } from 'vitest' | |
| import { Err, Ok } from './monad' | |
| describe('utils/monad', () => { | |
| it('works in sync', () => { | |
| function testOk() { | |
| return Ok(1) | |
| } | |
| function testErr() { | |
| return Err(new Error('test')) | |
| } | |
| let notError = true | |
| try { | |
| testOk() | |
| } | |
| catch { | |
| notError = false | |
| } | |
| expect(notError).toBe(true) | |
| let error = false | |
| try { | |
| testErr().expect('expect error occurred') | |
| } | |
| catch (err) { | |
| console.error(err) | |
| error = true | |
| } | |
| expect(error).toBe(true) | |
| }) | |
| it('works in async', async () => { | |
| async function testOk() { | |
| return Ok(1) | |
| } | |
| async function testErr() { | |
| return Err(new Error('async test')) | |
| } | |
| let notError = true | |
| try { | |
| await testOk() | |
| } | |
| catch { | |
| notError = false | |
| } | |
| expect(notError).toBe(true) | |
| let error = false | |
| try { | |
| (await testErr()).expect('expect async error occurred') | |
| } | |
| catch (err) { | |
| console.error(err) | |
| error = true | |
| } | |
| expect(error).toBe(true) | |
| }) | |
| }) |
This file contains hidden or 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
| import { useLogger } from '@tg-search/common' | |
| export interface Result<T> { | |
| orDefault: (defaultValue: T) => T | |
| orUndefined: () => T | undefined | |
| orElse: (fn: () => T) => T | |
| unwrap: () => T | |
| unwrapOver: (fn: (error: unknown) => void) => T | |
| expect: (message?: string) => T | |
| expectOver: (message?: string, fn?: (error: unknown) => void) => T | |
| map: <U>(fn: (value: T) => U) => Result<U> | |
| mapErr: (fn: (error: unknown) => T) => Result<T> | |
| } | |
| export function Ok<T>(value: T): Result<T> { | |
| return { | |
| orDefault: () => value, | |
| orUndefined: () => value, | |
| orElse: fn => fn(), | |
| unwrap: () => value, | |
| unwrapOver: () => value, | |
| expect: () => value, | |
| expectOver: () => value, | |
| map: (fn) => { | |
| try { | |
| return Ok(fn(value)) | |
| } | |
| catch (err: unknown) { | |
| return Err(err instanceof Error ? err : new Error(String(err))) | |
| } | |
| }, | |
| mapErr: (_fn) => { | |
| return Ok(value) | |
| }, | |
| } | |
| } | |
| export function Err<T>(error: unknown): Result<T> { | |
| useLogger('core:monnad').withError(error).warn('An error occurred') | |
| return { | |
| orDefault: (defaultValue: T) => defaultValue, | |
| orUndefined: () => undefined, | |
| orElse: fn => fn(), | |
| unwrap: () => { | |
| throw error | |
| }, | |
| unwrapOver: (fn) => { | |
| fn(error) | |
| throw error | |
| }, | |
| expect: (message?: string) => { | |
| const newError = new Error(message ?? 'Result is empty') | |
| newError.cause = error | |
| throw newError | |
| }, | |
| expectOver: (message, fn) => { | |
| fn?.(error) | |
| const newError = new Error(message ?? 'Result is empty') | |
| newError.cause = error | |
| throw newError | |
| }, | |
| map: () => { | |
| return Err(error) | |
| }, | |
| mapErr: (fn) => { | |
| return Err(fn(error)) | |
| }, | |
| } | |
| } | |
| // export interface Future<T> { | |
| // await: () => Result<Awaited<T>> | |
| // } | |
| // export function Async<T>(fn: () => Promise<T>): Future<T> { | |
| // return { | |
| // await: async () => { | |
| // try { | |
| // return Ok(await fn()) | |
| // } | |
| // catch (error) { | |
| // return Err<T>(error) | |
| // } | |
| // }, | |
| // } | |
| // } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment