extern crate reproto_ast as ast;
extern crate reproto_core as core;
extern crate reproto_manifest as manifest;
use core::{ContextItem, RelativePath, Resolver, RpPackage, RpVersionedPackage, Source};
use manifest::Lang;
use std::any::Any;
use std::cell::RefCell;
use std::rc::Rc;
use std::str;
pub enum Input<'input> {
File(ast::File<'input>, Option<RpVersionedPackage>),
Source(Source, Option<RpVersionedPackage>),
}
pub struct SimpleCompile<'a, 'input> {
pub input: Input<'input>,
pub package_prefix: Option<RpPackage>,
pub resolver: Option<&'a mut Resolver>,
pub items: Option<Rc<RefCell<Vec<ContextItem>>>>,
}
impl<'a, 'input> SimpleCompile<'a, 'input> {
pub fn new(input: Input<'input>) -> SimpleCompile<'a, 'input> {
Self {
input: input,
package_prefix: None,
resolver: None,
items: None,
}
}
pub fn package_prefix(self, package: RpPackage) -> Self {
Self {
package_prefix: Some(package),
..self
}
}
pub fn resolver(self, resolver: &'a mut Resolver) -> Self {
Self {
resolver: Some(resolver),
..self
}
}
pub fn with_items(self, items: Rc<RefCell<Vec<ContextItem>>>) -> Self {
Self {
items: Some(items),
..self
}
}
}
pub fn simple_compile<'a, 'input, O>(
mut out: O,
config: SimpleCompile<'a, 'input>,
modules: Vec<Box<Any>>,
lang: &Lang,
) -> core::errors::Result<()>
where
O: FnMut(&RelativePath, &str) -> core::errors::Result<()>,
{
let SimpleCompile {
input,
package_prefix,
resolver,
items,
} = config;
let mut empty_resolver = core::EmptyResolver;
let resolver = resolver.unwrap_or_else(|| &mut empty_resolver);
let capturing = core::CapturingFilesystem::new();
let ctx = core::Context::new(capturing.filesystem());
let ctx = if let Some(items) = items {
ctx.with_items(items)
} else {
ctx
};
let ctx = Rc::new(ctx);
let mut env = lang.into_env(ctx.clone(), package_prefix.clone(), resolver);
match input {
Input::File(file, package) => {
env.import_file(file, package)?;
}
Input::Source(source, package) => {
env.import_source(source, package)?;
}
}
let mut manifest = manifest::Manifest::default();
manifest.lang = Some(lang.copy());
manifest.modules = modules;
manifest.package_prefix = package_prefix;
lang.compile(ctx, env, manifest)?;
let borrowed = capturing.files().try_borrow()?;
let mut it = borrowed.iter().peekable();
while let Some((path, content)) = it.next() {
let content = str::from_utf8(content)?;
out(path, content)?;
}
Ok(())
}