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

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

export type Status =
    { readonly tag: "Pending" }
  | { readonly tag: "Shipped"; readonly tracking: string };

export const Status = {
  Pending: { tag: "Pending" } as Status,
  Shipped: (tracking: string): Status => ({ tag: "Shipped", tracking }),
};

export interface Order {
  readonly id: string;
  readonly price: number;
  readonly qty: number;
  readonly status: Status;
  readonly tags: readonly string[];
}

export const Order = {
};

export function save(o: Order): string {
  return JSON.stringify(serialise_Order(o));
}

export function load(s: string): Result<Order, JsonError> {
  return ((__s: string): Result<Order, JsonError> => { let __j: JsonValue; try { __j = JSON.parse(__s) as JsonValue; } catch (__e) { return Err({ kind: "Malformed", path: "$", message: String(__e) }); } const __r = deserialise_Order(__j, "$"); if (__r.tag === "Ok") return Ok(__r.value as Order); const __be = __r.error; return Err({ kind: __be.kind, path: (__be.kind === "StructuralMismatch" || __be.kind === "RefinementViolation") ? __be.path : "$", message: __be.kind === "StructuralMismatch" ? `expected ${__be.expected}, got ${String(__be.actual)}` : __be.kind === "RefinementViolation" ? __be.violation.message : __be.details }); })(s);
}

export function loadInferred(s: string): Result<Order, JsonError> {
  return ((__s: string): Result<Order, JsonError> => { let __j: JsonValue; try { __j = JSON.parse(__s) as JsonValue; } catch (__e) { return Err({ kind: "Malformed", path: "$", message: String(__e) }); } const __r = deserialise_Order(__j, "$"); if (__r.tag === "Ok") return Ok(__r.value as Order); const __be = __r.error; return Err({ kind: __be.kind, path: (__be.kind === "StructuralMismatch" || __be.kind === "RefinementViolation") ? __be.path : "$", message: __be.kind === "StructuralMismatch" ? `expected ${__be.expected}, got ${String(__be.actual)}` : __be.kind === "RefinementViolation" ? __be.violation.message : __be.details }); })(s);
}

export function loadMany(s: string): Result<readonly Order[], JsonError> {
  return ((__s: string): Result<readonly Order[], JsonError> => { let __j: JsonValue; try { __j = JSON.parse(__s) as JsonValue; } catch (__e) { return Err({ kind: "Malformed", path: "$", message: String(__e) }); } const __r = deserialise_List_Order(__j, "$"); if (__r.tag === "Ok") return Ok(__r.value as readonly Order[]); const __be = __r.error; return Err({ kind: __be.kind, path: (__be.kind === "StructuralMismatch" || __be.kind === "RefinementViolation") ? __be.path : "$", message: __be.kind === "StructuralMismatch" ? `expected ${__be.expected}, got ${String(__be.actual)}` : __be.kind === "RefinementViolation" ? __be.violation.message : __be.details }); })(s);
}

export function describe(s: string): string {
  const __r0 = ((__s: string): Result<Order, JsonError> => { let __j: JsonValue; try { __j = JSON.parse(__s) as JsonValue; } catch (__e) { return Err({ kind: "Malformed", path: "$", message: String(__e) }); } const __r = deserialise_Order(__j, "$"); if (__r.tag === "Ok") return Ok(__r.value as Order); const __be = __r.error; return Err({ kind: __be.kind, path: (__be.kind === "StructuralMismatch" || __be.kind === "RefinementViolation") ? __be.path : "$", message: __be.kind === "StructuralMismatch" ? `expected ${__be.expected}, got ${String(__be.actual)}` : __be.kind === "RefinementViolation" ? __be.violation.message : __be.details }); })(s);
  switch (__r0.tag) {
    case "Ok": {
      const o = __r0.value;
      return o.id;
    }
    case "Err": {
      const e = __r0.error;
      return e.kind.concat(" at ").concat(e.path).concat(": ").concat(e.message);
    }
  }
  throw new Error("non-exhaustive match");
}

export function serialise_Order(value: Order): JsonValue {
  return {
    id: value.id as JsonValue,
    price: ((v: number) => { if (!Number.isFinite(v)) throw new Error("non-finite Float at boundary"); return v as JsonValue; })(value.price),
    qty: value.qty as JsonValue,
    status: serialise_Status(value.status),
    tags: serialise_List_String(value.tags),
  };
}

export function deserialise_Order(json: JsonValue, path: string = "$"): Result<Order, 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["id"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.id`, expected: "string", actual: typeof obj["id"] });
  }
  const __id = obj["id"];
  if (typeof obj["price"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.price`, expected: "number", actual: typeof obj["price"] });
  }
  if (!Number.isFinite(obj["price"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.price`, expected: "finite number", actual: String(obj["price"]) });
  }
  const __price = obj["price"];
  if (typeof obj["qty"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.qty`, expected: "number", actual: typeof obj["qty"] });
  }
  if (!Number.isInteger(obj["qty"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.qty`, expected: "integer", actual: String(obj["qty"]) });
  }
  const __qty = obj["qty"];
  const __r_status = deserialise_Status(obj["status"], `${path}.status`);
  if (__r_status.tag === "Err") return __r_status;
  const __status = __r_status.value;
  const __r_tags = deserialise_List_String(obj["tags"], `${path}.tags`);
  if (__r_tags.tag === "Err") return __r_tags;
  const __tags = __r_tags.value;
  return Ok({ id: __id, price: __price, qty: __qty, status: __status, tags: __tags } as Order);
}

export function serialise_Status(value: Status): JsonValue {
  switch (value.tag) {
    case "Pending":
      return { kind: "Pending" };
    case "Shipped": {
      return { kind: "Shipped", tracking: (value as any).tracking as JsonValue };
    }
  }
}

export function deserialise_Status(json: JsonValue, path: string = "$"): Result<Status, 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 };
  const kind = obj["kind"];
  switch (kind) {
    case "Pending":
      return Ok({ tag: "Pending" } as Status);
    case "Shipped": {
  if (typeof obj["tracking"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.tracking`, expected: "string", actual: typeof obj["tracking"] });
  }
  const __tracking = obj["tracking"];
      return Ok({ tag: "Shipped", tracking: __tracking } as Status);
    }
    default:
      return Err({ kind: "StructuralMismatch", path, expected: "sum variant kind", actual: String(kind) });
  }
}


export function serialise_List_Order(value: readonly Order[]): JsonValue {
  return value.map((v) => serialise_Order(v));
}

export function deserialise_List_Order(json: JsonValue, path: string = "$"): Result<readonly Order[], BoundaryError> {
  if (!Array.isArray(json)) {
    return Err({ kind: "StructuralMismatch", path, expected: "array", actual: typeof json });
  }
  const out: Order[] = [];
  for (let i = 0; i < json.length; i++) {
  const item = json[i];
  const __r_el = deserialise_Order(item, `${path}[${i}]`);
  if (__r_el.tag === "Err") return __r_el;
  const __el = __r_el.value;
  out.push(__el);
  }
  return Ok(out);
}

export function serialise_List_String(value: readonly string[]): JsonValue {
  return value.map((v) => v as JsonValue);
}

export function deserialise_List_String(json: JsonValue, path: string = "$"): Result<readonly string[], BoundaryError> {
  if (!Array.isArray(json)) {
    return Err({ kind: "StructuralMismatch", path, expected: "array", actual: typeof json });
  }
  const out: string[] = [];
  for (let i = 0; i < json.length; i++) {
  const item = json[i];
  if (typeof item !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}[${i}]`, expected: "string", actual: typeof item });
  }
  const __el = item;
  out.push(__el);
  }
  return Ok(out);
}

