import {HttpMessage} from "@http4t/core/contract"; import {isFailure, success} from "@http4t/result"; import {MessageLens, RoutingResult} from "../lenses"; export type Lenses = { [K in keyof T]: MessageLens }; export class NamedLenses implements MessageLens { constructor(private readonly lenses: Lenses) { } async get(output: TMessage): Promise> { const value: T = {} as T; for (const [k, lens] of Object.entries(this.lenses)) { const result: RoutingResult = await (lens as MessageLens).get(output); // you only get one lens failure (the first lens failure) // and it's hard to debug which lens failed if (isFailure(result)) { return result; } value[k as keyof T] = result.value; } return success(value); } set(into: SetInto, value: T): Promise { const injectField = async (message: Promise, [k, lens]: [string, unknown]): Promise => { return await (lens as MessageLens).set(await message, value[k as keyof T]); }; return Object.entries(this.lenses).reduce(injectField, Promise.resolve(into)); } } export function named(lenses: Lenses): MessageLens { return new NamedLenses(lenses); }