All files / util/src/json-equal/deepEqualCodegen v1.ts

97.91% Statements 47/48
95.83% Branches 23/24
100% Functions 2/2
97.67% Lines 42/43

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    3x 10120x 10120x 10120x     10120x 8052x 3x 8049x 1x   8048x   8052x       2068x 879x 879x 2862x 2862x 2862x   879x       1189x 9x 9x 9x 9x 9x 9x       1180x 1177x 1177x 1177x     1177x 6864x 6864x 6864x   1177x       3x 3x 3x           3x 394x 394x   394x     394x    
import type {JavaScript} from '@jsonjoy.com/codegen';
 
const codegenValue = (doc: unknown, code: string[], r: number): number => {
  let rr = r;
  const type = typeof doc;
  const isPrimitive = doc === null || type === 'boolean' || type === 'string' || type === 'number';
 
  // Primitives
  if (isPrimitive) {
    if (doc === Infinity) {
      code.push(`if(r${r} !== Infinity)return false;`);
    } else if (doc === -Infinity) {
      code.push(`if(r${r} !== -Infinity)return false;`);
    } else {
      code.push(`if(r${r} !== ${JSON.stringify(doc)})return false;`);
    }
    return rr;
  }
 
  // Arrays
  if (Array.isArray(doc)) {
    code.push(`if(!Array.isArray(r${r}) || r${r}.length !== ${doc.length})return false;`);
    for (let i = 0; i < doc.length; i++) {
      rr++;
      code.push(`var r${rr}=r${r}[${i}];`);
      rr = codegenValue(doc[i], code, rr);
    }
    return rr;
  }
 
  // Uint8Array
  if (doc instanceof Uint8Array) {
    const length = doc.length;
    code.push(`if(!(r${r} instanceof Uint8Array) || r${r}.length !== ${length})return false;`);
    let condition = '';
    for (let i = 0; i < length; i++) condition += (condition ? '||' : '') + `(r${r}[${i}]!==${doc[i]})`;
    if (condition) code.push(`if(${condition})return false;`);
    return rr;
  }
 
  // Objects
  if (type === 'object' && doc) {
    const obj = doc as Record<string, unknown>;
    const keys = Object.keys(obj);
    code.push(
      `if(!r${r} || typeof r${r} !== "object" || Array.isArray(r${r}) || Object.keys(r${r}).length !== ${keys.length})return false;`,
    );
    for (const key of keys) {
      rr++;
      code.push(`var r${rr}=r${r}[${JSON.stringify(key)}];`);
      rr = codegenValue(obj[key], code, rr);
    }
    return rr;
  }
 
  // Undefined
  Eif (doc === undefined) {
    code.push(`if(r${r} !== undefined)return false;`);
    return rr;
  }
 
  return rr;
};
 
export const deepEqualCodegen = (a: unknown): JavaScript<(b: unknown) => boolean> => {
  const code: string[] = [];
  codegenValue(a, code, 0);
 
  const fn = ['(function(r0){', ...code, 'return true;', '})'];
 
  // return fn.join('\n') as JavaScript<(b: unknown) => boolean>;
  return fn.join('') as JavaScript<(b: unknown) => boolean>;
};