// Generated by bynkc — do not edit by hand.
// commons pricing

import { Ok, Err, Some, None, type Result, type Option, type ValidationError } from "./runtime.js";

export type Price = number & { readonly __brand: "Price" };

export const Price = {
  of(value: number): Result<Price, ValidationError> {
    if (!Number.isFinite(value)) {
      return Err({ field: "Price", message: "must be a finite number", value });
    }
    if (!(value > 0)) {
      return Err({ field: "Price", message: "must be positive", value });
    }
    return Ok(value as Price);
  },
  unsafe(value: number): Price {
    return value as Price;
  },
};

export type Ratio = number & { readonly __brand: "Ratio" };

export const Ratio = {
  of(value: number): Result<Ratio, ValidationError> {
    if (!Number.isFinite(value)) {
      return Err({ field: "Ratio", message: "must be a finite number", value });
    }
    if (!(value >= 0.0 && value <= 1.0)) {
      return Err({ field: "Ratio", message: "must be in range [0.0, 1.0]", value });
    }
    return Ok(value as Ratio);
  },
  unsafe(value: number): Ratio {
    return value as Ratio;
  },
};

export function toCents(p: number): number {
  return Math.round((p * 100.0));
}

export function fromCents(c: number): number {
  return c / 100.0;
}

export function roundings(f: number): number {
  return Math.round(f) + Math.floor(f) + Math.ceil(f) + Math.trunc(f);
}

export function mkPrice(raw: number): Result<Price, ValidationError> {
  return Price.of(raw);
}

export function discounted(p: Price, r: Ratio): number {
  return p * r;
}

export function demo(): boolean {
  const half: Ratio = Ratio.unsafe(0.5);
  const __r0 = mkPrice(19.99);
  switch (__r0.tag) {
    case "Ok": {
      const p = __r0.value;
      return discounted(p, half) > 9.0;
    }
    case "Err": {
      return false;
    }
  }
  throw new Error("non-exhaustive match");
}

