All files / src/draw/glyph tees.ts

100% Statements 50/50
100% Branches 5/5
100% Functions 4/4
100% Lines 50/50

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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 961x 1x 1x 1x 1x     1x 2x 2x 2x 2x                             1x       1x 1x 1x 1x 1x 1x           1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                             1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x             1x   1242x 1242x 1242x 1242x  
import {Record} from '#util'
import {K, type EndoOf, dual} from '#Function'
import {segmentString} from '#String'
import {type TupleOf} from 'effect/Types'
import {type Direction, directions} from '../direction.js'
import type {TeeSet} from './types.js'
 
const _replaceTee = (
  set: TeeSet,
  direction: Direction,
  glyph: string,
): TeeSet => Record.modify(set, direction, K(glyph))
 
/**
 * Given a direction and a glyph, replaces the tee at this direction in a given
 * tee set with the given glyph and returns the new tee set.
 *
 * At the key `named` you will find a version that does the same but accepts a
 * _name_ of a tee set instead of an tee set.
 * @param set Tee set to change.
 * @param direction A {@link Direction} of the glyph to be changed.
 * @param glyph String of new glyph.
 * @returns Updated tee set.
 * @category drawing
 * @function
 */
export const replaceTee: {
  (set: TeeSet, direction: Direction, glyph: string): TeeSet
  (direction: Direction, glyph: string): EndoOf<TeeSet>
  named: (direction: Direction, glyph: string) => (name: TeeSetName) => TeeSet
} = Object.assign(dual(3, _replaceTee), {
  named:
    (direction: Direction, glyph: string) =>
    (name: TeeSetName): TeeSet =>
      _replaceTee(teeSet(name), direction, glyph),
})
 
/**
 * Names of all tee sets.
 * @category drawing
 */
export const teeSetNames = [
  'ascii',
  'double',
  'hDouble',
  'hThick',
  'solid',
  'space',
  'thick',
  'thin',
  'vDouble',
  'vThick',
  'vThickTop',
  'vThickBottom',
] as const
 
/**
 * The type of a tee set name.
 * @category drawing
 */
export type TeeSetName = (typeof teeSetNames)[number]
 
/**
 * A record of all tee sets. A tee set has a tee glyph defined for each tee
 * direction. The tees are grouped into sets by style.
 * @category drawing
 */
export type TeeSets = Record<TeeSetName, TeeSet>
 
const teeSets: TeeSets = {
  ascii: Record.monoRecord('+')(...directions),
  double: fromQuad('╩╠╦╣'),
  hDouble: fromQuad('╧╞╤╡'),
  hThick: fromQuad('┷┝┯┥'),
  solid: Record.monoRecord('█')(...directions),
  space: Record.monoRecord(' ')(...directions),
  thick: fromQuad('┻┣┳┫'),
  thin: fromQuad('┴├┬┤'),
  vDouble: fromQuad('╨╟╥╢'),
  vThick: fromQuad('┸┠┰┨'),
  vThickTop: fromQuad('┴┞┰┦'),
  vThickBottom: fromQuad('┸┟┬┧'),
}
 
/**
 * Get a tee set by name.
 * @category drawing
 * @function
 */
export const teeSet = (name: TeeSetName): TeeSet => teeSets[name]
 
function fromQuad(s: string): TeeSet {
  const [top, right, bottom, left] = segmentString(s) as TupleOf<4, string>
  return {top, right, bottom, left}
}