Skip to content

Commit

Permalink
1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobWeisenburger committed Feb 17, 2024
1 parent fdc85ab commit f20c67a
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 207 deletions.
79 changes: 28 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,73 +49,50 @@ bun add @weis-guys/result
## Getting Started

```ts
import { Result } from '@weis-guys/result'
import Result from '@weis-guys/result'

const okResult = Result.ok( 'good value' )
// { success: true, value: "good value" }

const happy = Result.ok( 'good value' )
console.log( happy )
// { success: true, value: "good value" }
const warningResult = Result.okWithWarning( 'good value', 'some kind of warning' )
// { success: true, value: "good value", warning: "some kind of warning" }


const sad = Result.err( 'some kind of error' )
console.log( sad )
const errorResult = Result.error( 'some kind of error' )
// { success: false, error: "some kind of error" }


/**
* this function could return a value or an error
* this function could return a value, an error, or a value with a warning
*/
function someFn () {
return Math.random() > 0.5 ? happy : sad
const items = [ okResult, warningResult, errorResult ]
return items[ Math.floor( Math.random() * items.length ) ]
}


const result = someFn()
console.log( { result } )

Result.match( result )( {
ok: value => console.log( value ), // do something with the value
err: error => console.error( error ), // do something with the error
} )

const valueOrError = Result.match( result )( {
// optionally perform a typesafe transformation to the value before returning it
ok: value => value,

// optionally perform a typesafe transformation to the error before returning it
err: error => error,
} )

console.log( 'valueOrError:', valueOrError )
// valueOrError: "good value" | "some kind of error"

type ValueOrError = typeof valueOrError
// type ValueOrError = "good value" | "some kind of error"


const justValue = Result.match( result )( { ok: value => value } )
console.log( 'justValue:', justValue )
// justValue: "good value" | undefined

type JustValue = typeof justValue
// type JustValue = "good value" | undefined

if ( result.success ) {
console.log( result.value )
// 'good value'

const justError = Result.match( result )( { err: error => error } )
console.log( 'justError:', justError )
// justError: "some kind of error" | undefined
result.warning && console.warn( result.warning )
// 'some kind of warning'
} else {
console.error( result.error )
// 'some kind of error'
}

type JustError = typeof justError
// type JustError = "some kind of error" | undefined
const value = Result.getValue( result )
console.log( value )
// 'good value' | undefined

const warning = Result.getWarning( result )
console.log( warning )
// 'some kind of warning' | undefined

// you can also handle both cases with a normal if/else statement
if ( result.success ) {
console.log( 'result.value:', result.value )
// result.value: "good value"
} else {
console.log( 'result.error', result.error )
// result.error: "some kind of error"
}
const error = Result.getError( result )
console.log( error )
// 'some kind of error' | undefined
```

## TODO
Expand Down
79 changes: 44 additions & 35 deletions docs/examples.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,44 @@
// import { Result } from '@weis-guys/result'

// const ok = Result.ok( 'good value' )
// // { type: 'ok', value: 'good value' }

// const warning = Result.warning( 'some kind of warning' )
// // { type: 'warning', value: 'some kind of warning' }

// const error = Result.error( 'some kind of error' )
// // { type: 'error', value: 'some kind of error' }

// /**
// * this function could return a value or an error
// */
// function someFn () {
// const items = [ ok, warning, error ]
// return items[ Math.floor( Math.random() * items.length ) ]
// }

// const result = someFn()

// switch ( result.type ) {
// case 'ok':
// console.log( result.value )
// // 'good value'
// break
// case 'warning':
// console.warn( result.value )
// // 'some kind of warning'
// break
// case 'error':
// console.error( result.value )
// // 'some kind of error'
// break
// }
import Result from '@weis-guys/result'

const okResult = Result.ok( 'good value' )
// { success: true, value: "good value" }

const warningResult = Result.okWithWarning( 'good value', 'some kind of warning' )
// { success: true, value: "good value", warning: "some kind of warning" }

const errorResult = Result.error( 'some kind of error' )
// { success: false, error: "some kind of error" }

/**
* this function could return a value, an error, or a value with a warning
*/
function someFn () {
const items = [ okResult, warningResult, errorResult ]
return items[ Math.floor( Math.random() * items.length ) ]
}

const result = someFn()
console.log( { result } )

if ( result.success ) {
console.log( result.value )
// 'good value'

result.warning && console.warn( result.warning )
// 'some kind of warning'
} else {
console.error( result.error )
// 'some kind of error'
}

const value = Result.getValue( result )
console.log( value )
// 'good value' | undefined

const warning = Result.getWarning( result )
console.log( warning )
// 'some kind of warning' | undefined

const error = Result.getError( result )
console.log( error )
// 'some kind of error' | undefined
11 changes: 4 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@weis-guys/result",
"version": "0.0.6",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"author": "Jacob Weisenburger",
Expand All @@ -12,13 +12,10 @@
"typescript"
],
"scripts": {
"test": "bun test",
"test:watch": "bun test --watch",
"docs:examples": "clear && bun run --watch docs/examples.ts",
"build": "clear && bun run scripts/build.ts",
"build:watch": "clear && bun --watch run scripts/build.ts",
"test": "bun test --watch",
"examples": "clear && bun run --watch docs/examples.ts",
"build": "clear && bun --watch run scripts/build.ts",
"publish": "clear && bun run scripts/publish.ts",
"publish:watch": "clear && bun --watch run scripts/publish.ts",
"cmd": "cmd.exe /c start cmd /k wsl --cd ~/software/weis-guys/result"
},
"devDependencies": {
Expand Down
6 changes: 5 additions & 1 deletion scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ await Promise.resolve()
sourcemap: 'inline',
target: 'node',
plugins: [
dts()
dts( {
output: {
noBanner: true,
}
} )
],
}
await Bun.build( config )
Expand Down
67 changes: 67 additions & 0 deletions src/Result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export module Result {
export type Ok<Value, Warning = undefined> = {
success: true
/**
* an intended value
*/
value: Value
/**
* a non-fatal error
*/
warning?: Warning
}

export type Err<Error> = {
success: false
/**
* a fatal error
*/
error: Error
}

export type Any<Value = any, Error = any, Warning = any> =
| Ok<Value, Warning>
| Err<Error>

/**
* return a successful result
*/
export function ok<const Value> ( x: Value ): Ok<Value> {
return { success: true, value: x }
}

/**
* return a successful result with a warning
*/
export function okWithWarning<const Value, const Warning> ( x: Value, warning: Warning ): Ok<Value, Warning> {
return { ...ok( x ), warning }
}

/**
* return a failure result
*/
export function error<const Error> ( x: Error ): Err<Error> {
return { success: false, error: x }
}

/**
* return only the value if the result is a success
*/
export function getValue<Result extends Any> ( result: Result ) {
return result.success ? result.value : undefined
}

/**
* return only the warning if the result is a success
*/
export function getWarning<Result extends Any> ( result: Result ) {
return result.success ? result.warning : undefined
}

/**
* return only the error if the result is a failure
*/
export function getError<Result extends Any> ( result: Result ) {
return result.success ? undefined : result.error
}
}
78 changes: 19 additions & 59 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,37 @@
import { expect, test } from 'bun:test'
import { Result } from './index'
import Result from './index'

const ok = Result.ok( 'good value' )
// { type: 'ok', value: 'good value' }
const okResult = Result.ok( 'good value' )
// { success: true, value: "good value" }

const warning = Result.warning( 'some kind of warning' )
// { type: 'warning', value: 'some kind of warning' }
const warningResult = Result.okWithWarning( 'good value', 'some kind of warning' )
// { success: true, value: "good value", warning: "some kind of warning" }

const error = Result.error( 'some kind of error' )
// { type: 'error', value: 'some kind of error' }
const errorResult = Result.error( 'some kind of error' )
// { success: false, error: "some kind of error" }

/**
* this function could return a value or an error
*/
function someFn () {
const items = [ ok, warning, error ]
const items = [ okResult, warningResult, errorResult ]
return items[ Math.floor( Math.random() * items.length ) ]
}

const result = someFn()
console.log( { result } )

const matched = Result.match( result )( {
ok: value => 42,
warning: warning => 'warning',
error: error => 'error',
test( 'Result.getValue', () => {
expect( Result.getValue( result ) )
.toBe( result.success ? result.value : undefined )
} )
console.log( { matched } )

const matched2 = Result.match( result )( {} )

// switch ( result.type ) {
// case 'ok':
// console.log( result.value )
// // 'good value'
// break
// case 'warning':
// console.warn( result.value )
// // 'some kind of warning'
// break
// case 'error':
// console.error( result.value )
// // 'some kind of error'
// break
// }


// test( 'result should make Result Type', () => {
// expect( result ).toMatchObject( {
// type: result.type,
// value: result.value,
// } )
// } )

// test( 'Result.match should allow ok and err callbacks', () => {
// const foo = Result.match( result )( {
// ok: value => value,
// err: error => error,
// } )
// if ( result.success ) expect( foo ).toBe( result.value )
// else expect( foo ).toBe( result.error )
// } )

// test( 'Result.match should allow just ok callback', () => {
// const foo = Result.match( result )( {
// ok: value => value,
// } )
// if ( result.success ) expect( foo ).toBe( result.value )
// } )
test( 'Result.getWarning', () => {
expect( Result.getWarning( result ) )
.toBe( result.success ? result.warning : undefined )
} )

// test( 'Result.match should allow just err callback', () => {
// const foo = Result.match( result )( {
// err: error => error,
// } )
// if ( !result.success ) expect( foo ).toBe( result.error )
// } )
test( 'Result.getError', () => {
expect( Result.getError( result ) )
.toBe( result.success ? undefined : result.error )
} )
Loading

0 comments on commit f20c67a

Please sign in to comment.