Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-vcs/src/lib.rs')
| -rw-r--r-- | helix-vcs/src/lib.rs | 132 |
1 files changed, 0 insertions, 132 deletions
diff --git a/helix-vcs/src/lib.rs b/helix-vcs/src/lib.rs deleted file mode 100644 index 4c5f2036..00000000 --- a/helix-vcs/src/lib.rs +++ /dev/null @@ -1,132 +0,0 @@ -//! `helix_vcs` provides types for working with diffs from a Version Control System (VCS). -//! Currently `git` is the only supported provider for diffs, but this architecture allows -//! for other providers to be added in the future. - -use anyhow::{anyhow, bail, Result}; -use arc_swap::ArcSwap; -use std::{ - path::{Path, PathBuf}, - sync::Arc, -}; - -#[cfg(feature = "git")] -mod git; - -mod diff; - -pub use diff::{DiffHandle, Hunk}; - -mod status; - -pub use status::FileChange; - -/// Contains all active diff providers. Diff providers are compiled in via features. Currently -/// only `git` is supported. -#[derive(Clone)] -pub struct DiffProviderRegistry { - providers: Vec<DiffProvider>, -} - -impl DiffProviderRegistry { - /// Get the given file from the VCS. This provides the unedited document as a "base" - /// for a diff to be created. - pub fn get_diff_base(&self, file: &Path) -> Option<Vec<u8>> { - self.providers - .iter() - .find_map(|provider| match provider.get_diff_base(file) { - Ok(res) => Some(res), - Err(err) => { - log::debug!("{err:#?}"); - log::debug!("failed to open diff base for {}", file.display()); - None - } - }) - } - - /// Get the current name of the current [HEAD](https://stackoverflow.com/questions/2304087/what-is-head-in-git). - pub fn get_current_head_name(&self, file: &Path) -> Option<Arc<ArcSwap<Box<str>>>> { - self.providers - .iter() - .find_map(|provider| match provider.get_current_head_name(file) { - Ok(res) => Some(res), - Err(err) => { - log::debug!("{err:#?}"); - log::debug!("failed to obtain current head name for {}", file.display()); - None - } - }) - } - - /// Fire-and-forget changed file iteration. Runs everything in a background task. Keeps - /// iteration until `on_change` returns `false`. - pub fn for_each_changed_file( - self, - cwd: PathBuf, - f: impl Fn(Result<FileChange>) -> bool + Send + 'static, - ) { - tokio::task::spawn_blocking(move || { - if self - .providers - .iter() - .find_map(|provider| provider.for_each_changed_file(&cwd, &f).ok()) - .is_none() - { - f(Err(anyhow!("no diff provider returns success"))); - } - }); - } -} - -impl Default for DiffProviderRegistry { - fn default() -> Self { - // currently only git is supported - // TODO make this configurable when more providers are added - let providers = vec![ - #[cfg(feature = "git")] - DiffProvider::Git, - DiffProvider::None, - ]; - DiffProviderRegistry { providers } - } -} - -/// A union type that includes all types that implement [DiffProvider]. We need this type to allow -/// cloning [DiffProviderRegistry] as `Clone` cannot be used in trait objects. -/// -/// `Copy` is simply to ensure the `clone()` call is the simplest it can be. -#[derive(Copy, Clone)] -enum DiffProvider { - #[cfg(feature = "git")] - Git, - None, -} - -impl DiffProvider { - fn get_diff_base(&self, file: &Path) -> Result<Vec<u8>> { - match self { - #[cfg(feature = "git")] - Self::Git => git::get_diff_base(file), - Self::None => bail!("No diff support compiled in"), - } - } - - fn get_current_head_name(&self, file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> { - match self { - #[cfg(feature = "git")] - Self::Git => git::get_current_head_name(file), - Self::None => bail!("No diff support compiled in"), - } - } - - fn for_each_changed_file( - &self, - cwd: &Path, - f: impl Fn(Result<FileChange>) -> bool, - ) -> Result<()> { - match self { - #[cfg(feature = "git")] - Self::Git => git::for_each_changed_file(cwd, f), - Self::None => bail!("No diff support compiled in"), - } - } -} |