pub mod ast;
pub mod canonical;
pub mod codegen;
pub mod compat;
pub mod diagnostic;
pub mod errors;
pub mod ir;
pub mod lexer;
pub mod lower;
pub mod meta;
pub mod parser;
pub mod project;
pub mod remap;
pub mod resolve;
pub mod span;
pub mod typeck;
pub mod validate;
pub use codegen::{CodegenBackend, CodegenError};
pub use ir::{CompiledSchema, ResolvedType, TypeDef, TypeId, TypeRegistry};
pub use meta::{meta_schema, pack_schema};
pub use project::compile_project;
pub use project::ProjectResult;
pub use resolve::SchemaLoader;
pub use diagnostic::{edit_distance, find_closest_match, find_similar_matches};
pub use diagnostic::{Diagnostic, ErrorClass, ErrorCode, Note, Severity};
pub use errors::{did_you_mean, edit_distance as errors_edit_distance};
use ast::Schema;
#[derive(Debug)]
pub struct ParseResult {
pub schema: Option<Schema>,
pub diagnostics: Vec<Diagnostic>,
}
pub fn parse(source: &str) -> ParseResult {
let (tokens, mut diagnostics) = lexer::lex(source);
let (schema, parse_diags) = parser::parse(source, tokens);
diagnostics.extend(parse_diags);
if let Some(ref schema) = schema {
let validate_diags = validate::validate(schema);
diagnostics.extend(validate_diags);
}
ParseResult {
schema,
diagnostics,
}
}
#[derive(Debug)]
pub struct CompileResult {
pub schema: Option<Schema>,
pub compiled: Option<CompiledSchema>,
pub diagnostics: Vec<Diagnostic>,
}
impl CompileResult {
pub fn is_ok(&self) -> bool {
!self.has_errors()
}
pub fn has_errors(&self) -> bool {
self.diagnostics
.iter()
.any(|d| d.severity == Severity::Error)
}
pub fn warnings(&self) -> Vec<&Diagnostic> {
self.diagnostics
.iter()
.filter(|d| d.severity == Severity::Warning)
.collect()
}
pub fn errors(&self) -> Vec<&Diagnostic> {
self.diagnostics
.iter()
.filter(|d| d.severity == Severity::Error)
.collect()
}
}
pub fn compile(source: &str) -> CompileResult {
compile_impl(source, false)
}
fn compile_impl(source: &str, allow_reserved: bool) -> CompileResult {
let (tokens, mut diagnostics) = lexer::lex(source);
let (schema, parse_diags) = parser::parse(source, tokens);
diagnostics.extend(parse_diags);
if let Some(ref schema) = schema {
let validate_diags = if allow_reserved {
validate::validate_allow_reserved(schema)
} else {
validate::validate(schema)
};
diagnostics.extend(validate_diags);
}
if diagnostics.iter().any(|d| d.severity == Severity::Error) {
return CompileResult {
schema,
compiled: None,
diagnostics,
};
}
let Some(schema) = schema else {
return CompileResult {
schema: None,
compiled: None,
diagnostics,
};
};
let (mut compiled, lower_diags) = lower::lower(&schema);
diagnostics.extend(lower_diags);
if let Some(ref mut compiled) = compiled {
let check_diags = typeck::check(compiled);
diagnostics.extend(check_diags);
}
CompileResult {
schema: Some(schema),
compiled,
diagnostics,
}
}