All files / src/impl AutoCloseOne.impl.ts

100% Statements 18/18
100% Branches 8/8
100% Functions 6/6
100% Lines 18/18

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 5825x 25x   25x           25x 1180x                   3351x 3351x 999x         5x       1177x 1177x   1177x 2x     1175x 1175x   1175x         1180x             1180x        
import { AutoClose, AutoCloseOne, AutoCloseType, typeToAutoClose, unwrapAutoClose } from "@jonloucks/contracts-ts/api/AutoClose";
import { isPresent, OptionalType, RequiredType } from "@jonloucks/contracts-ts/api/Types";
import { AtomicReference } from "@jonloucks/contracts-ts/auxiliary/AtomicReference";
import { create as createAtomicReference } from "./AtomicReference.impl";
 
/**
 * Create an AutoCloseOne instance.
 * @returns the AutoCloseOne implementation
 */
export function create(): RequiredType<AutoCloseOne> {
  return AutoCloseOneImpl.internalCreate();
}
 
// ---- Implementation details below ----
 
/**
 * AutoCloseOne implementation.
 */
class AutoCloseOneImpl implements AutoCloseOne {
  close(): void {
    let autoClose = this.#reference.get();
    if (isPresent(autoClose) && this.#reference.compareAndSet(autoClose, null)) {
      autoClose.close();
    }
  }
 
  [Symbol.dispose](): void {
    this.close();
  }
 
  set(newClose: OptionalType<AutoCloseType>): void {
    const current = this.#reference.get();
    const validNewClose = isPresent(newClose) ? typeToAutoClose(newClose) : newClose;
 
    if (unwrapAutoClose(current) === unwrapAutoClose(validNewClose)) {
      return; // no change
    }
 
    try {
      this.close(); // close current value if present
    } finally {
      this.#reference.set(validNewClose);
    }
  }
 
  static internalCreate(): RequiredType<AutoCloseOne> {
    return new AutoCloseOneImpl();
  }
 
  private constructor() {
    // empty
  }
 
  readonly #reference: AtomicReference<AutoClose> = createAtomicReference<AutoClose>();
}