import {HttpMessage} from "@http4t/core/contract"; import {isFailure, success} from "@http4t/result"; import {MessageLens, RoutingResult} from "../lenses"; export class IntersectionLens implements MessageLens { constructor(private readonly a: MessageLens, private readonly b: MessageLens, private readonly unintersectA: (intersected: A & B) => Promise | A, private readonly unintersectB: (intersected: A & B) => Promise | B ) { } async get(message: TMessage): Promise> { const aResult = await this.a.get(message); if (isFailure(aResult)) { return aResult; } const bResult = await this.b.get(message); if (isFailure(bResult)) { return bResult; } return success(aResult.value === undefined && bResult.value === undefined ? undefined as any : {...aResult.value, ...bResult.value}); } async set(into: SetInto, value: A & B): Promise { const a = await this.a.set(into, await this.unintersectA(value)); return this.b.set(a, await this.unintersectB(value)); } } export function intersect( a: MessageLens, b: MessageLens): MessageLens; export function intersect( a: MessageLens, b: MessageLens): MessageLens; export function intersect( a: MessageLens, b: MessageLens, unintersectA: (intersected: A & B) => Promise | A, unintersectB: (intersected: A & B) => Promise | B): MessageLens; export function intersect( a: MessageLens, b: MessageLens, unintersectA?: (intersected: A & B) => Promise | A, unintersectB?: (intersected: A & B) => Promise | B): MessageLens { const unintersectA1 = unintersectA || (async (_) => undefined) as (intersected: A & B) => Promise; const unintersectB1 = unintersectB || (async (ab) => ab) as (intersected: A & B) => Promise; return new IntersectionLens(a, b, unintersectA1 as any, unintersectB1 as any); }