summaryrefslogtreecommitdiff
path: root/support/texlab/src/distro/file_name_db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/distro/file_name_db.rs')
-rw-r--r--support/texlab/src/distro/file_name_db.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/support/texlab/src/distro/file_name_db.rs b/support/texlab/src/distro/file_name_db.rs
new file mode 100644
index 0000000000..9234d0a3f9
--- /dev/null
+++ b/support/texlab/src/distro/file_name_db.rs
@@ -0,0 +1,80 @@
+use std::{
+ borrow::Borrow,
+ path::{Path, PathBuf},
+};
+
+use anyhow::Result;
+use rustc_hash::FxHashSet;
+
+use crate::db::Language;
+
+#[derive(Debug)]
+pub struct DistroFile(PathBuf);
+
+impl DistroFile {
+ pub fn path(&self) -> &Path {
+ &self.0
+ }
+
+ pub fn name(&self) -> &str {
+ self.0.file_name().unwrap().to_str().unwrap()
+ }
+}
+
+impl PartialEq for DistroFile {
+ fn eq(&self, other: &Self) -> bool {
+ self.name() == other.name()
+ }
+}
+
+impl Eq for DistroFile {}
+
+impl std::hash::Hash for DistroFile {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.name().hash(state)
+ }
+}
+
+impl Borrow<str> for DistroFile {
+ fn borrow(&self) -> &str {
+ self.name()
+ }
+}
+
+#[derive(Debug, Default)]
+pub struct FileNameDB {
+ files: FxHashSet<DistroFile>,
+}
+
+impl FileNameDB {
+ pub fn get(&self, name: &str) -> Option<&Path> {
+ self.files.get(name).map(|file| file.path())
+ }
+
+ pub fn iter(&self) -> impl Iterator<Item = (&str, &Path)> + '_ {
+ self.files.iter().map(|file| (file.name(), file.path()))
+ }
+
+ pub fn parse(
+ root_dirs: &[PathBuf],
+ reader: &mut dyn FnMut(&Path) -> Result<Vec<PathBuf>>,
+ ) -> Result<Self> {
+ let files = root_dirs
+ .iter()
+ .flat_map(|dir| reader(dir))
+ .flatten()
+ .filter_map(|rel_path| {
+ Language::from_path(&rel_path)?;
+ rel_path.file_name()?.to_str()?;
+ let abs_path = root_dirs
+ .iter()
+ .rev()
+ .map(|dir| dir.join(&rel_path))
+ .find_map(|path| std::fs::canonicalize(path).ok())?;
+ Some(DistroFile(abs_path))
+ })
+ .collect();
+
+ Ok(Self { files })
+ }
+}