pub mod source;
pub mod targets;
pub mod typescript;
pub use source::{Builder, Module, Root};
#[cfg(test)]
mod tests {
use super::*;
use facet::Facet;
use phon_schema::{
DecodeLimits, SchemaBundleLimits, schema_bundle_from_bytes, schema_from_bytes,
schema_to_bytes,
};
#[derive(Facet)]
struct Point {
x: u32,
y: u32,
}
#[derive(Facet)]
#[repr(u8)]
#[allow(dead_code)]
enum Shape {
Circle(f64),
Rectangle { width: f64, height: f64 },
Point,
}
#[derive(Facet)]
#[allow(dead_code)]
struct Person {
name: String,
age: u32,
email: Option<String>,
tags: Vec<String>,
home: Point,
favorite: Shape,
big: u64,
}
fn module() -> Module {
Builder::new().add::<Person>().build().unwrap()
}
#[test]
fn every_schema_byte_blob_round_trips() {
let m = module();
assert!(!m.schemas.is_empty());
for s in &m.schemas {
let bytes = schema_to_bytes(s);
let (back, _) =
schema_from_bytes(&bytes, DecodeLimits::DEFAULT).expect("schema round-trips");
assert_eq!(&back, s, "schema {:#x} must round-trip", s.id.as_u64());
}
}
#[test]
fn emitted_schema_bundle_is_complete_and_admitted() {
let module = module();
let bytes = typescript::schema_bundle_bytes(&module).expect("schema bundle encodes");
let bundle = schema_bundle_from_bytes(&bytes, SchemaBundleLimits::default())
.expect("schema bundle admits");
assert_eq!(bundle.schemas(), module.schemas);
}
#[test]
fn typescript_renders_the_expected_shapes() {
let ts = typescript::render(&module());
assert!(
ts.contains("export interface Person {"),
"missing Person:\n{ts}"
);
assert!(ts.contains("name: string;"));
assert!(ts.contains("age: number;")); assert!(ts.contains("big: bigint;")); assert!(ts.contains("email: string | null;")); assert!(ts.contains("tags: string[];")); assert!(ts.contains("home: Point;")); assert!(ts.contains("favorite: Shape;"));
assert!(ts.contains("export type Shape ="), "missing Shape:\n{ts}");
assert!(ts.contains(r#"{ tag: "Circle"; value: number }"#)); assert!(ts.contains(r#"{ tag: "Rectangle"; width: number; height: number }"#));
assert!(ts.contains(r#"{ tag: "Point" }"#));
assert!(ts.contains("export const registry = new Registry("));
assert!(ts.contains("export const schemaId = {"));
assert!(ts.contains("Person: 0x"));
assert!(ts.contains("export const schemaBundle = hexToBytes(\"50484f4e53434d31"));
assert!(!ts.contains("SCHEMA_BYTES"));
assert!(!ts.contains("schemaFromBytes"));
}
}