import { OptLazy } from '@rimbu/common'; import type { Link } from './index.mjs'; /** * A valued connection between two nodes, * being a 3-valued tuple of which the * first two elements are nodes and the last element a value * @typeparam N - the node type * @typeparam V - the value type */ export type ValuedLink = [N, N, V]; export namespace ValuedLink { export type Target = readonly [N, V]; export function fromArgs( node1: N, node2: N, value: V ): ValuedLink { return [node1, node2, value]; } } export type ValuedGraphElement = [N] | ValuedLink; export namespace ValuedGraphElement { /** * Returns true if the given graph element `e` is a single node. * Instructs the compiler that the type is a 1-tuple. * @param e - the graph element */ export function isSingleNode( e: ValuedGraphElement ): e is [unknown] { return e.length === 1; } /** * Returns true if the given graph element `e` is a 3-tuple. * Instructs the compiler that the type is a 3-tuple. * @param e - the graph element */ export function isLink( e: ValuedGraphElement ): e is [unknown, unknown, unknown] { return e.length !== 1; } /** * Returns the value of a single node graph element if the given element `e` is a single * node, or the given `otherwise` fallback value otherwise. * @param e - the graph element * @param otherwise - (default: undefined) the fallback value to return * if the given element is not a single node */ export function getSingleNode( e: ValuedGraphElement ): N | undefined; export function getSingleNode( e: ValuedGraphElement, otherwise?: OptLazy ): N | O { if (isSingleNode(e)) return e[0]; return OptLazy(otherwise!); } /** * Returns the nodes of the link graph element if the given element `e` is * a Link element, or undefined otherwise. * @param e - the graph element */ export function getLink( e: ValuedGraphElement ): Link | undefined { if (isLink(e)) return e; return undefined; } /** * Returns the element at the given `key` in the graph element `e`, * if the element is a Link element, or returns the given `otherwise` value * otherwise. * @param e - the graph element * @param key - the link key * @param otherwise - (default: undefined) the fallback value */ export function getLinkElement< N, V, K extends keyof ValuedGraphElement, >(e: ValuedGraphElement, key: K): ValuedLink[K] | undefined; export function getLinkElement< N, V, K extends keyof ValuedGraphElement, O, >( e: ValuedGraphElement, key: K, otherwise?: OptLazy ): ValuedLink[K] | O { if (isLink(e)) return e[key]; return OptLazy(otherwise!); } }