All files / json-path/src Parser.ts

94.28% Statements 33/35
80% Branches 16/20
100% Functions 8/8
100% Lines 30/30

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        6x           290x 290x 290x       290x 290x 290x       2676x       80x 80x 80x       10562x 10562x 10562x     10053x 10710x   2651x                   491x 491x 491x 491x       2666x       5903x 5903x   5903x 6164x   6164x 273x   5891x     5903x      
/**
 * Basic parser utility class for managing input string and position
 * in the parsing process.
 */
export class Parser {
  public str: string;
  public pos: number;
  public length: number;
 
  constructor() {
    this.str = '';
    this.pos = 0;
    this.length = 0;
  }
 
  public reset(input: string): void {
    this.str = input;
    this.pos = 0;
    this.length = input.length;
  }
 
  public eof(): boolean {
    return this.pos >= this.length;
  }
 
  public peek(len: number = 1): string {
    const {str, pos, length} = this;
    Iif (pos >= length) return '';
    return (len === 1 ? str[pos] : str.slice(pos, pos + len)) || '';
  }
 
  public is(expected: string): boolean {
    const {str, pos, length} = this;
    const expLen = expected.length;
    if (pos + expLen > length) return false;
 
    // Optimized: check character by character without creating substring
    for (let i = 0; i < expLen; i++) {
      if (str[pos + i] !== expected[i]) return false;
    }
    return true;
  }
 
  /**
   * Match the current position against a regular expression.
   *
   * @param reg - Regular expression to match against the current position.
   * @returns The length of the match if successful, otherwise 0.
   */
  public match(reg: RegExp): number {
    const {str, pos, length} = this;
    Iif (pos >= length) return 0;
    const m = str.slice(pos).match(reg);
    return m && m.index === 0 && m[0] ? m[0].length : 0;
  }
 
  public skip(count: number): void {
    this.pos += count;
  }
 
  public ws(): void {
    const {str, length} = this;
    let pos = this.pos;
    // Optimized: direct character code checks instead of regex
    while (pos < length) {
      const code = str.charCodeAt(pos);
      // Check for space (32), tab (9), newline (10), carriage return (13)
      if (code === 32 || code === 9 || code === 10 || code === 13) {
        pos++;
      } else {
        break;
      }
    }
    this.pos = pos;
  }
}