All files / core/systems/gars system.ts

100% Statements 10/10
100% Branches 0/0
100% Functions 4/4
100% Lines 10/10

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                    14x             14x   14x         2058x           14x     10028x       1006x 1006x                         14x               6x      
import { Option, pipe } from 'effect'
 
import { cellBox } from '../cell'
import { compact, makeParser } from '../parser'
import { singleReading } from '../reading'
import type { Formatter, Grid, Parser } from '../types'
import { fromGars, isGars, toGars } from './gars'
import { garsCellOutline, garsGrid } from './grid'
import type { GarsPrecision } from './precision'
 
const cellLabel: Record<GarsPrecision, string> = {
  30: '30′ cell',
  15: '15′ quadrant',
  5: '5′ keypad',
}
 
/** AGeoP-21 (B.7.2e): GARS is for deconfliction and must not define a location. */
export const AREA_CAUTION = 'an area, not a position'
 
export const formatter: Formatter = {
  id: 'GARS',
  label: 'GARS',
  maybeGridId: Option.some('Gars'),
  format: (point, { garsPrecision }) =>
    singleReading(
      toGars(point, garsPrecision),
      `${cellLabel[garsPrecision]}, area only`,
    ),
}
 
export const parser: Parser = makeParser(
  'GARS',
  text =>
    pipe(
      compact(text),
      Option.liftPredicate(isGars),
      Option.map(reference => {
        const cell = fromGars(reference)
        return {
          kind: 'GARS',
          point: {
            lat: (cell.south + cell.north) / 2,
            lon: (cell.west + cell.east) / 2,
          },
          maybeBounds: Option.some(cellBox(cell)),
        }
      }),
    ),
  Option.some(AREA_CAUTION),
)
 
export const grid: Grid = {
  id: 'Gars',
  label: 'GARS',
  description: 'GARS cells, from zoom 4',
  colors: { onDark: [229, 72, 77, 130], onLight: [196, 30, 45, 150] },
  isEnabledByDefault: false,
  build: garsGrid,
  maybeCueOutline: Option.some((point, { garsPrecision }) =>
    Option.some(garsCellOutline(toGars(point, garsPrecision))),
  ),
}