All files / src/types/kmx/kmx-plus-builder build-uset.ts

44.56% Statements 41/92
100% Branches 0/0
0% Functions 0/2
44.56% Lines 41/92

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 931x 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 1x 1x 1x 1x                              
import { constants } from "@keymanapp/ldml-keyboard-constants";
import { KMXPlus } from "@keymanapp/common-types";
import { build_strs_index, BUILDER_STR_REF, BUILDER_STRS } from "./build-strs.js";
import { BUILDER_SECTION, BUILDER_U32CHAR } from "./builder-section.js";
 
import KMXPlusData = KMXPlus.KMXPlusData;
import StrsItem = KMXPlus.StrsItem;
import UsetItem = KMXPlus.UsetItem;
 
/** reference from build_uset_index */
export type BUILDER_USET_REF = number;
 
interface BUILDER_USET_USET {
  range: number;
  count: number;
  pattern: BUILDER_STR_REF;
  _pattern: StrsItem; // for sorting
};
 
interface BUILDER_USET_RANGE {
  start: BUILDER_U32CHAR; // uchar32
  end: BUILDER_U32CHAR; // uchar32
}
 
export interface BUILDER_USET extends BUILDER_SECTION {
  usetCount: number;
  rangeCount: number;
  usets: BUILDER_USET_USET[];
  ranges: BUILDER_USET_RANGE[];
};
 
/**
* Builder for the 'uset' section
*/
export function build_uset(kmxplus: KMXPlusData, sect_strs: BUILDER_STRS ) : BUILDER_USET {
  if(!kmxplus?.uset?.usets) {
    return null;
  }

  // uset items in pattern order
  const items = [...kmxplus.uset.usets]
    .sort((a,b) => a.compareTo(b));

  const ranges : BUILDER_USET_RANGE[] = [];

  const usets : BUILDER_USET_USET[] = [];

  items.forEach(set => {
    usets.push({
      range: ranges.length, // index
      count: set.uset.length,
      pattern: build_strs_index(sect_strs, set.str),
      _pattern: set.str,
    });
    // append the ranges
    set.uset.ranges.forEach(([start, end]) => ranges.push({ start, end }));
  });

  const uset: BUILDER_USET = {
    ident: constants.hex_section_id(constants.section.uset),
    size: constants.length_uset +
      (constants.length_uset_uset * usets.length) +
      (constants.length_uset_range * ranges.length),
    usetCount: usets.length,
    rangeCount: ranges.length,
    usets,
    ranges,
    _offset: 0,
  };

  return uset;
}
 
 
/**
 * @returns uset index
 */
export function build_uset_index(sect_uset: BUILDER_USET, value: UsetItem) {
  if(!(value instanceof UsetItem)) {
    if (value === null) {
      throw new Error('unexpected null UsetItem');
    } else {
      throw new Error('Expected UsetItem but got '+ value);
    }
  }

  const result = sect_uset.usets.findIndex(v => v._pattern.value === value.str.value);
  if(result < 0) {
    throw new Error('unexpectedly missing UsetItem ' + value.uset.toString());
  }
  return result;
}