1mod schema;
11mod targets;
12
13use serde::Deserialize;
14use thiserror::Error;
15
16pub use schema::{ContractSchema, Property, PropertyKind};
17
18#[derive(Debug, Error)]
19pub enum CompileError {
20 #[error("contract schema is not valid JSON Schema 2020-12: {message}")]
21 InvalidSchema { message: String },
22 #[error(
23 "construct '{construct}' does not round-trip to all targets; \
24 use one of the supported alternatives: {alternatives}"
25 )]
26 Unrepresentable {
27 construct: String,
28 alternatives: String,
29 },
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
33#[serde(rename_all = "lowercase")]
34pub enum Target {
35 Zod,
36 Pydantic,
37 Rust,
38 Sql,
39}
40
41#[derive(Debug)]
42pub struct CompileRequest {
43 pub contract_name: String,
44 pub schema_json: String,
45 pub target: Target,
46 pub epoch: u32,
47}
48
49#[derive(Debug)]
50pub struct CompiledBinding {
51 pub content: String,
52}
53
54pub fn compile(request: &CompileRequest) -> Result<CompiledBinding, CompileError> {
61 let schema = schema::parse(&request.contract_name, &request.schema_json)?;
62 let content = match request.target {
63 Target::Zod => targets::zod::emit(&schema, request.epoch),
64 Target::Pydantic => targets::pydantic::emit(&schema, request.epoch),
65 Target::Rust => targets::rust::emit(&targets::rust::EmitInput {
66 schema: &schema,
67 raw_schema_json: &request.schema_json,
68 epoch: request.epoch,
69 })?,
70 Target::Sql => targets::sql::emit(&schema, request.epoch),
71 };
72 Ok(CompiledBinding { content })
73}