nautilus_schema/lib.rs
1//! Nautilus Schema Parser and Validator
2//!
3//! This crate provides end-to-end processing of `.nautilus` schema files.
4//!
5//! # Pipeline
6//!
7//! Processing a schema runs in four stages:
8//! - **Lexer** — converts source text into typed tokens with span tracking.
9//! - **Parser** — builds a syntax [`ast::Schema`] via recursive descent.
10//! - **Validator** — performs multi-pass semantic validation and emits a fully
11//! resolved [`ir::SchemaIr`].
12//! - **Formatter** — renders an AST back to canonical source text.
13//!
14//! # Quick Start
15//!
16//! The [`analyze`] function runs the full pipeline in one call and collects all
17//! diagnostics:
18//!
19//! ```ignore
20//! use nautilus_schema::analyze;
21//!
22//! let result = analyze(source);
23//! for diag in &result.diagnostics {
24//! eprintln!("{:?} — {}", diag.severity, diag.message);
25//! }
26//! if let Some(ir) = &result.ir {
27//! println!("{} models validated", ir.models.len());
28//! }
29//! ```
30//!
31//! # Visitor Pattern
32//!
33//! The [`visitor`] module provides a trait-based visitor for flexible AST traversal:
34//!
35//! ```ignore
36//! use nautilus_schema::{visitor::{Visitor, walk_model}, ast::*, Result};
37//!
38//! struct ModelCounter { count: usize }
39//!
40//! impl Visitor for ModelCounter {
41//! fn visit_model(&mut self, model: &ModelDecl) -> Result<()> {
42//! self.count += 1;
43//! walk_model(self, model)
44//! }
45//! }
46//! ```
47
48#![warn(missing_docs)]
49#![forbid(unsafe_code)]
50
51pub mod analysis;
52pub mod ast;
53pub mod bool_expr;
54pub mod diagnostic;
55mod error;
56pub mod formatter;
57pub mod ir;
58mod lexer;
59pub mod parser;
60mod span;
61pub mod sql_expr;
62mod token;
63mod validator;
64pub mod visitor;
65
66pub use analysis::{
67 analyze, completion, goto_definition, hover, semantic_tokens, AnalysisResult, CompletionItem,
68 CompletionKind, HoverInfo, SemanticKind, SemanticToken,
69};
70pub use ast::ComputedKind;
71pub use diagnostic::{Diagnostic, Severity};
72pub use error::{Result, SchemaError};
73pub use formatter::format_schema;
74pub use lexer::Lexer;
75pub use parser::Parser;
76pub use span::{Position, Span};
77pub use token::{Token, TokenKind};
78pub use validator::validate_schema;
79
80/// Resolve `env(VAR_NAME)` syntax in a connection URL.
81///
82/// If `raw` matches the pattern `env(...)`, the value of the named
83/// environment variable is returned. Otherwise `raw` is returned as-is.
84pub fn resolve_env_url(raw: &str) -> std::result::Result<String, String> {
85 if raw.starts_with("env(") && raw.ends_with(')') {
86 let var = &raw[4..raw.len() - 1];
87 std::env::var(var).map_err(|_| format!("environment variable '{}' is not set", var))
88 } else {
89 Ok(raw.to_string())
90 }
91}