remove treehouse-format crate and collapse everything into src

This commit is contained in:
りき萌 2025-07-10 16:50:41 +02:00
parent ca127a9411
commit b792688776
66 changed files with 145 additions and 112 deletions

136
src/sources.rs Normal file
View file

@ -0,0 +1,136 @@
use std::{collections::HashMap, ops::ControlFlow};
use anyhow::{anyhow, Context};
use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
use tracing::{info_span, instrument};
use crate::{
config::Config,
dirs::Dirs,
html::navmap::NavigationMap,
import_map::ImportMap,
parse::parse_tree_with_diagnostics,
state::{report_diagnostics, Source, Treehouse},
tree::SemaRoots,
vfs::{self, Cd, Content, VPath, VPathBuf},
};
pub struct Sources {
pub config: Config,
pub treehouse: Treehouse,
pub navigation_map: NavigationMap,
pub import_map: ImportMap,
}
impl Sources {
pub fn load(dirs: &Dirs) -> anyhow::Result<Self> {
let config = {
let _span = info_span!("load_config").entered();
let mut config: Config = toml_edit::de::from_str(
&vfs::query::<Content>(&dirs.root, VPath::new_const("treehouse.toml"))
.map(Content::string)
.ok_or_else(|| anyhow!("config file does not exist"))??,
)
.context("failed to deserialize config")?;
config.site = std::env::var("TREEHOUSE_SITE").unwrap_or(config.site);
config.autopopulate_emoji(&*dirs.emoji)?;
config.autopopulate_pics(&*dirs.pic)?;
config.load_syntaxes(dirs.syntax.clone())?;
config
};
let treehouse = load_trees(&config, dirs)?;
let navigation_map = NavigationMap::build(
&treehouse,
treehouse.files_by_tree_path[VPath::new("index")],
);
let import_map = ImportMap::generate(
&config.site,
&Cd::new(dirs.static_.clone(), VPathBuf::new("js")),
&config.build.javascript.import_roots,
);
Ok(Sources {
config,
treehouse,
navigation_map,
import_map,
})
}
}
#[instrument(skip(config, dirs))]
fn load_trees(config: &Config, dirs: &Dirs) -> anyhow::Result<Treehouse> {
let mut treehouse = Treehouse::new();
let mut diagnostics = vec![];
let mut parsed_trees = HashMap::new();
let mut paths = vec![];
vfs::walk_dir_rec(&*dirs.content, VPath::ROOT, &mut |path| {
if path.extension() == Some("tree") {
paths.push(path.to_owned());
}
ControlFlow::Continue(())
});
// NOTE: Sources are filled in later; they can be left out until a call to report_diagnostics.
let file_ids: Vec<_> = paths
.iter()
.map(|path| treehouse.add_file(path.clone(), Source::Other(String::new())))
.collect();
let parse_results: Vec<_> = {
let _span = info_span!("load_trees::parse").entered();
paths
.into_par_iter()
.zip(&file_ids)
.flat_map(|(path, &file_id)| {
vfs::query::<Content>(&dirs.content, &path)
.and_then(|c| c.string().ok())
.map(|input| {
let parse_result = parse_tree_with_diagnostics(file_id, &input);
(path, file_id, input, parse_result)
})
})
.collect()
};
for (path, file_id, input, _) in &parse_results {
let tree_path = path.with_extension("");
treehouse
.files_by_tree_path
.insert(tree_path.clone(), *file_id);
treehouse.set_source(
*file_id,
Source::Tree {
input: input.clone(),
tree_path,
},
);
}
{
let _span = info_span!("load_trees::sema").entered();
for (path, file_id, _, result) in parse_results {
match result {
Ok(roots) => {
let roots = SemaRoots::from_roots(
&mut treehouse,
&mut diagnostics,
config,
file_id,
roots,
);
treehouse.roots.insert(file_id, roots);
parsed_trees.insert(path, file_id);
}
Err(mut parse_diagnostics) => diagnostics.append(&mut parse_diagnostics),
}
}
}
report_diagnostics(&treehouse, &diagnostics)?;
Ok(treehouse)
}