import {HttpMessage} from "@http4t/core/contract"; import {failure, isFailure, success} from "@http4t/result"; import {MessageLens, routeFailedError, RoutingError, RoutingResult} from "../lenses"; import {responseOf} from "@http4t/core/responses"; export type StaticValueOpts = { equality: (expected: T, actual: T) => boolean, failure: (value: T) => RoutingError }; function defaults(value: T): StaticValueOpts { return { equality: (a: T, b: T) => a as any === b, failure: v => routeFailedError(`Expected: ${value}, but got: ${v}`, [], responseOf(400)) }; } export class StaticValueLens implements MessageLens { private readonly opts: StaticValueOpts; constructor(private readonly value: T, private readonly lens: MessageLens, opts: Partial>) { this.opts = Object.assign({}, defaults(value), opts); } async get(from: TMessage): Promise> { const actual = await this.lens.get(from); if (isFailure(actual)) return actual; if (this.opts.equality(this.value, actual.value)) { return success(undefined); } return failure(this.opts.failure(actual.value)); } async set(into: SetInto, value: undefined): Promise { return this.lens.set(into, this.value); } } export function value( value: T, lens: MessageLens, opts: Partial> = {}): MessageLens { return new StaticValueLens(value, lens, opts) }