All files / src/codec graph.ts

100% Statements 23/23
87.5% Branches 7/8
100% Functions 2/2
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 451x 1x 1x 1x                             1x 1x 1x 1x 1x 1x 1x 11x 11x 11x 11x 11x 1x             1x 1x 11x 1x   1x 1x  
import {map, type Tree} from '#tree'
import {Graph, Option, pipe} from 'effect'
import {Isomorphism} from 'effect-ts-laws/typeclass'
import {EdgeListIsomorphism} from './Isomorphism.js'
 
/**
 * Convert a tree into an
 * [Effect Graph](https://effect-ts.github.io/effect/effect/Graph.ts.html).
 *
 * A `Tree<A>` is converted into a `DirectedGraph<A, “”>`: a directed graph
 * with nodes of type `A` and an empty string associated with each edge.
 *
 * We do this in two steps. First we replace the tree nodes with their graph
 * node Id giving us a tree of node Ids, then we get the edge list of this tree
 * and add each edge to the graph.
 * @category codec
 * @function
 */
export const treeToGraph = <A>(self: Tree<A>): Graph.Graph<A, ''> =>
  Graph.directed((mutable: Graph.MutableDirectedGraph<A, ''>) => {
    for (const [child, maybeParent] of pipe(
      self,
      map(a => Graph.addNode(mutable, a)),
      Isomorphism.encode(EdgeListIsomorphism<number>()),
    )) {
      pipe(
        maybeParent,
        Option.map(parent => Graph.addEdge(mutable, child, parent, '')),
      )
    }
  })
 
/**
 * Return a GraphViz representation of a numeric or string tree.
 * @category codec
 * @function
 */
export const treeToGraphViz = (self: Tree<number> | Tree<string>): string => {
  const tree: Tree<string> = map(self as Tree<number>, s =>
    typeof s === 'number' ? s.toString() : s,
  )
 
  return pipe(tree, treeToGraph, Graph.toGraphViz)
}