pushkin-compiler 0.1.0

Schema compiler for pushkin: canonical JSON Schema emission and generated bindings
Documentation
//! Target emitters. Each produces a deterministic, epoch-stamped, strict
//! binding. Rust emission generates through the pinned `typify`
//! `TypeSpace`, with a `schemars` round-trip suite pinning fidelity in
//! tests (PHASE-LOG: Phase 6 task 2 — the typify swap that discharged
//! the R5 condition; history of the earlier hand-rolled emitter lives
//! there, not here). The Zod, Pydantic, and SQL emitters are hand-rolled
//! string assembly. For every target, the constrained-subset parser in
//! `schema.rs` stays the loud FRONT gate: emitters only ever receive
//! already-validated schemas (N6/§5.1).

pub mod pydantic;
pub mod rust;
pub mod sql;
pub mod zod;

use crate::schema::ContractSchema;

/// Shared generated-file header (spec §5.2 schema-epoch header).
pub fn header(schema: &ContractSchema, epoch: u32, comment: &str) -> String {
    format!(
        "{comment} GENERATED by pushkin compile from contract '{name}' — do not hand-edit.\n\
         {comment} pushkin-epoch: {epoch}\n",
        name = schema.contract_name,
    )
}

/// `user` → `UserCreate` (matches the Phase 0 spike's naming convention).
pub fn type_name(schema: &ContractSchema) -> String {
    let mut pascal = String::new();
    for part in schema.contract_name.split(['-', '_']) {
        let mut chars = part.chars();
        if let Some(first) = chars.next() {
            pascal.extend(first.to_uppercase());
            pascal.push_str(chars.as_str());
        }
    }
    format!("{pascal}Create")
}

/// Produces a double-quoted literal valid in both JavaScript and Python.
pub fn quoted_string(value: &str) -> String {
    let mut output = String::with_capacity(value.len() + 2);
    output.push('"');
    for character in value.chars() {
        match character {
            '"' => output.push_str("\\\""),
            '\\' => output.push_str("\\\\"),
            '\n' => output.push_str("\\n"),
            '\r' => output.push_str("\\r"),
            '\t' => output.push_str("\\t"),
            '\u{0008}' => output.push_str("\\b"),
            '\u{000C}' => output.push_str("\\f"),
            '\u{2028}' => output.push_str("\\u2028"),
            '\u{2029}' => output.push_str("\\u2029"),
            control if control.is_control() => {
                use std::fmt::Write as _;
                let _ = write!(output, "\\u{:04x}", u32::from(control));
            }
            other => output.push(other),
        }
    }
    output.push('"');
    output
}