use std::{
env,
error::Error,
fmt, fs,
io::{self, Write},
path::PathBuf,
};
use tectonic_errors::prelude::*;
use crate::document::Document;
#[derive(Debug)]
pub struct Workspace {
#[allow(dead_code)] root_dir: PathBuf,
doc: Document,
}
impl Workspace {
pub fn first_document(&self) -> &Document {
&self.doc
}
pub fn first_document_mut(&mut self) -> &mut Document {
&mut self.doc
}
pub fn open_from_environment() -> Result<Self> {
let initial_dir = env::current_dir()?;
let mut root_dir = initial_dir.clone();
root_dir.push("tmp");
while root_dir.pop() {
root_dir.push("Tectonic.toml");
let mut doc_file = match fs::File::open(&root_dir) {
Ok(f) => f,
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
root_dir.pop(); continue; }
Err(e) => return Err(e.into()),
};
root_dir.pop();
let mut doc_build_dir = root_dir.clone();
doc_build_dir.push("build");
let doc = Document::new_from_toml(root_dir.clone(), doc_build_dir, &mut doc_file)?;
return Ok(Workspace { root_dir, doc });
}
Err(NoWorkspaceFoundError { initial_dir }.into())
}
}
#[derive(Debug)]
pub struct NoWorkspaceFoundError {
initial_dir: PathBuf,
}
impl fmt::Display for NoWorkspaceFoundError {
fn fmt(&self, f: &mut fmt::Formatter) -> StdResult<(), fmt::Error> {
write!(
f,
"could not find `Tectonic.toml` in `{}` or any parent directory",
self.initial_dir.display()
)
}
}
impl Error for NoWorkspaceFoundError {}
#[derive(Debug)]
pub struct WorkspaceCreator {
pub(crate) root_dir: PathBuf,
}
impl WorkspaceCreator {
pub fn new<P: Into<PathBuf>>(root_dir: P) -> Self {
WorkspaceCreator {
root_dir: root_dir.into(),
}
}
pub fn create(self, bundle_loc: String, extra_paths: Vec<PathBuf>) -> Result<Workspace> {
let doc = Document::create_for(&self, bundle_loc, extra_paths)?;
let mut tex_dir = self.root_dir.clone();
tex_dir.push("src");
atry!(
fs::create_dir_all(&tex_dir);
["couldn\'t create workspace directory `{}`", tex_dir.display()]
);
doc.create_toml()?;
{
tex_dir.push("_preamble.tex");
let mut f = fs::File::create(&tex_dir)?;
f.write_all(
br"\documentclass{article}
\title{My Title}
\begin{document}
",
)?;
tex_dir.pop();
}
{
tex_dir.push("index.tex");
let mut f = fs::File::create(&tex_dir)?;
f.write_all(
br"Hello, world.
",
)?;
tex_dir.pop();
}
{
tex_dir.push("_postamble.tex");
let mut f = fs::File::create(&tex_dir)?;
f.write_all(
br"\end{document}
",
)?;
tex_dir.pop();
}
Ok(Workspace {
root_dir: self.root_dir,
doc,
})
}
}