// Generated by bynkc — do not edit by hand.
// commons commerce.money

import { Ok, Err, Some, None, type Result, type Option, type ValidationError, type JsonValue, type BoundaryError, type ServiceBinding, callService, boundaryError } from "../runtime.js";

export type CurrencyCode = string & { readonly __brand: "CurrencyCode" };

export const CurrencyCode = {
  of(value: string): Result<CurrencyCode, ValidationError> {
    if (!new RegExp("^" + "[A-Z]{3}" + "$").test(value)) {
      return Err({ field: "CurrencyCode", message: "must match /[A-Z]{3}/", value });
    }
    return Ok(value as CurrencyCode);
  },
  unsafe(value: string): CurrencyCode {
    return value as CurrencyCode;
  },
};

export interface Money {
  readonly minorUnits: number;
  readonly currency: CurrencyCode;
}

export const Money = {
};

export function serialise_CurrencyCode(value: CurrencyCode): JsonValue {
  return value as unknown as string;
}

export function deserialise_CurrencyCode(json: JsonValue, path: string = "$"): Result<CurrencyCode, BoundaryError> {
  if (typeof json !== "string") {
    return Err({ kind: "StructuralMismatch", path, expected: "string", actual: typeof json });
  }
  const validated = (typeof (CurrencyCode as any).of === "function")
    ? (CurrencyCode as any).of(json)
    : Ok(json as unknown as CurrencyCode);
  if (validated.tag === "Err") {
    return Err({ kind: "RefinementViolation", path, violation: validated.error });
  }
  return Ok(validated.value as CurrencyCode);
}

export function serialise_Money(value: Money): JsonValue {
  return {
    minorUnits: value.minorUnits as JsonValue,
    currency: serialise_CurrencyCode(value.currency),
  };
}

export function deserialise_Money(json: JsonValue, path: string = "$"): Result<Money, BoundaryError> {
  if (typeof json !== "object" || json === null || Array.isArray(json)) {
    return Err({ kind: "StructuralMismatch", path, expected: "object", actual: typeof json });
  }
  const obj = json as { [k: string]: JsonValue };
  if (typeof obj["minorUnits"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.minorUnits`, expected: "number", actual: typeof obj["minorUnits"] });
  }
  if (!Number.isInteger(obj["minorUnits"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.minorUnits`, expected: "integer", actual: String(obj["minorUnits"]) });
  }
  const __minorUnits = obj["minorUnits"];
  const __r_currency = deserialise_CurrencyCode(obj["currency"], `${path}.currency`);
  if (__r_currency.tag === "Err") return __r_currency;
  const __currency = __r_currency.value;
  return Ok({ minorUnits: __minorUnits, currency: __currency } as Money);
}


