Skip to content

Commit

Permalink
refactor(flow): Result
Browse files Browse the repository at this point in the history
  • Loading branch information
niuiic committed Mar 24, 2024
1 parent b290288 commit f8e44ef
Showing 1 changed file with 24 additions and 24 deletions.
48 changes: 24 additions & 24 deletions packages/core/src/flow/result.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isPromise } from '@/utils'
import { isPromise, toStr } from '@/utils'

/**
* To describe a result of program.
Expand All @@ -12,80 +12,80 @@ import { isPromise } from '@/utils'
* {@link https://github.com/niuiic/fx-flow/blob/main/packages/test/src/flow/result.spec.ts | More examples}
*/
class Result<T> {
private success: boolean
private ok: boolean
private err: string | undefined
private data: T | undefined

public constructor(args: { err: string } | { data: T }) {
if ('err' in args && !('data' in args)) {
this.err = args.err
this.success = false
this.ok = false
} else if ('data' in args && !('err' in args)) {
this.data = args.data
this.success = true
this.ok = true
} else {
throw new Error('Wrong arguments')
throw new Error('Result constructor: arguments are wrong')
}
}

/** Return data of result if result is success, or throw an error */
public unwrap(): T {
if (this.success) {
if (this.ok) {
return this.data as T
}
throw new Error('Result is failure')
throw new Error(this.err)
}

/** Return data of result if result is success, or return `data` */
public unwrapOr(data: T) {
if (this.success) {
if (this.ok) {
return this.data as T
}
return data
}

/** Return data of result if result is success, or return the result of `fn` */
public unwrapOrElse(fn: (err: string) => T): T {
if (this.success) {
if (this.ok) {
return this.data as T
}
return fn(this.err!)
}

/** Return error message if result is failure */
public error() {
if (!this.success) {
if (!this.ok) {
return this.err
}
}

/** Return a result whose data is the result of `fn`, if result is success */
public map<R>(fn: (data: T) => R): Result<R> {
if (!this.success) {
if (!this.ok) {
return new Result({ err: this.err! })
}
return new Result({ data: fn(this.data as T) })
}

/** Return a result whose data is the result of `fn`, if result is success, or `data` */
public mapOr<R>(fn: (data: T) => R, data: R): Result<R> {
if (!this.success) {
if (!this.ok) {
return new Result({ data })
}
return new Result({ data: fn(this.data as T) })
}

/** Return a result whose data is the result of `fn`, if result is success, or the result of `fn2` */
public mapOrElse<R>(fn: (data: T) => R, fn2: (err: string) => R): Result<R> {
if (!this.success) {
if (!this.ok) {
return new Result({ data: fn2(this.err!) })
}
return new Result({ data: fn(this.data as T) })
}

/** Return a result with the same data of the original one if result is success or return a result with `err` */
public mapErr(err: string): Result<T> {
if (this.success) {
if (this.ok) {
return new Result({ data: this.data as T })
} else {
return new Result({ err })
Expand All @@ -98,30 +98,30 @@ class Result<T> {
* - Result<T> -> Promise<Result<T>>
*/
public async wait(): Promise<Result<Awaited<T>>> {
if (this.success) {
if (isPromise(this.data)) {
const data = await this.data
return new Result<Awaited<T>>({ data: data as Awaited<T> })
}
return new Result<Awaited<T>>({ data: this.data as Awaited<T> })
} else {
if (!this.ok) {
return new Result<Awaited<T>>({ err: this.err! })
}
if (isPromise(this.data)) {
return this.data
.then((x) => new Result<Awaited<T>>({ data: x as Awaited<T> }))
.catch((x) => new Result<Awaited<T>>({ err: toStr(x) }))
}
return new Result<Awaited<T>>({ data: this.data as Awaited<T> })
}

/** Check if result is success */
public isOk() {
return this.success
return this.ok
}

/** Check if result is failure */
public isErr() {
return !this.success
return !this.ok
}

// Check if data is a promise
public isPromise() {
return this.success && isPromise(this.data)
return this.ok && isPromise(this.data)
}
}

Expand Down

0 comments on commit f8e44ef

Please sign in to comment.