mod driver;
pub use brink_driver::AnalysisOptions;
pub use brink_ir::{DiagnosticCode, FileId};
use brink_format::StoryData;
use std::io;
use std::path::Path;
#[derive(Debug, Clone)]
pub struct ResolvedDiagnostic {
pub path: String,
pub file: FileId,
pub range: rowan::TextRange,
pub message: String,
pub code: DiagnosticCode,
}
#[derive(Debug)]
pub struct CompileOutput {
pub data: StoryData,
pub warnings: Vec<ResolvedDiagnostic>,
}
pub struct LirOutput {
pub program: brink_ir::lir::Program,
pub warnings: Vec<ResolvedDiagnostic>,
}
pub fn compile_path(path: &Path) -> Result<CompileOutput, CompileError> {
compile(path.to_string_lossy().as_ref(), |p| {
std::fs::read_to_string(p).map_err(|e| io::Error::new(e.kind(), format!("{p}: {e}")))
})
}
pub fn compile<F>(entry: &str, read_file: F) -> Result<CompileOutput, CompileError>
where
F: FnMut(&str) -> Result<String, io::Error>,
{
driver::compile(entry, read_file)
}
pub fn compile_with_options<F>(
entry: &str,
read_file: F,
options: AnalysisOptions,
) -> Result<CompileOutput, CompileError>
where
F: FnMut(&str) -> Result<String, io::Error>,
{
driver::compile_with_options(entry, read_file, options)
}
pub fn compile_to_json<F>(entry: &str, read_file: F) -> Result<brink_json::InkJson, CompileError>
where
F: FnMut(&str) -> Result<String, io::Error>,
{
let lir_output = driver::compile_to_lir(entry, read_file)?;
Ok(brink_codegen_json::emit(&lir_output.program))
}
pub fn compile_string_to_json(source: &str) -> Result<brink_json::InkJson, CompileError> {
compile_to_json("<string>", |_| Ok(source.to_string()))
}
#[derive(Debug, thiserror::Error)]
pub enum CompileError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("{} diagnostic(s) prevented compilation", .0.len())]
Diagnostics(Vec<ResolvedDiagnostic>),
#[error("circular INCLUDE dependency: {0}")]
CircularInclude(String),
}
impl From<brink_driver::DiscoverError> for CompileError {
fn from(err: brink_driver::DiscoverError) -> Self {
match err {
brink_driver::DiscoverError::Io(e) => Self::Io(e),
brink_driver::DiscoverError::CircularInclude(msg) => Self::CircularInclude(msg),
}
}
}