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.rs69
1 files changed, 43 insertions, 26 deletions
diff --git a/helix-vcs/src/lib.rs b/helix-vcs/src/lib.rs
index 4c5f2036..7225c38e 100644
--- a/helix-vcs/src/lib.rs
+++ b/helix-vcs/src/lib.rs
@@ -1,7 +1,3 @@
-//! `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::{
@@ -10,6 +6,11 @@ use std::{
};
#[cfg(feature = "git")]
+pub use git::Git;
+#[cfg(not(feature = "git"))]
+pub use Dummy as Git;
+
+#[cfg(feature = "git")]
mod git;
mod diff;
@@ -20,16 +21,39 @@ mod status;
pub use status::FileChange;
-/// Contains all active diff providers. Diff providers are compiled in via features. Currently
-/// only `git` is supported.
+#[doc(hidden)]
+#[derive(Clone, Copy)]
+pub struct Dummy;
+impl Dummy {
+ fn get_diff_base(&self, _file: &Path) -> Result<Vec<u8>> {
+ bail!("helix was compiled without git support")
+ }
+
+ fn get_current_head_name(&self, _file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> {
+ bail!("helix was compiled without git support")
+ }
+
+ fn for_each_changed_file(
+ &self,
+ _cwd: &Path,
+ _f: impl Fn(Result<FileChange>) -> bool,
+ ) -> Result<()> {
+ bail!("helix was compiled without git support")
+ }
+}
+
+impl From<Dummy> for DiffProvider {
+ fn from(value: Dummy) -> Self {
+ DiffProvider::Dummy(value)
+ }
+}
+
#[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()
@@ -43,7 +67,6 @@ impl DiffProviderRegistry {
})
}
- /// 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()
@@ -81,40 +104,34 @@ 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,
- ];
+ let providers = vec![Git.into()];
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 {
+#[derive(Clone)]
+pub enum DiffProvider {
+ Dummy(Dummy),
#[cfg(feature = "git")]
- Git,
- None,
+ Git(Git),
}
impl DiffProvider {
fn get_diff_base(&self, file: &Path) -> Result<Vec<u8>> {
match self {
+ Self::Dummy(inner) => inner.get_diff_base(file),
#[cfg(feature = "git")]
- Self::Git => git::get_diff_base(file),
- Self::None => bail!("No diff support compiled in"),
+ Self::Git(inner) => inner.get_diff_base(file),
}
}
fn get_current_head_name(&self, file: &Path) -> Result<Arc<ArcSwap<Box<str>>>> {
match self {
+ Self::Dummy(inner) => inner.get_current_head_name(file),
#[cfg(feature = "git")]
- Self::Git => git::get_current_head_name(file),
- Self::None => bail!("No diff support compiled in"),
+ Self::Git(inner) => inner.get_current_head_name(file),
}
}
@@ -124,9 +141,9 @@ impl DiffProvider {
f: impl Fn(Result<FileChange>) -> bool,
) -> Result<()> {
match self {
+ Self::Dummy(inner) => inner.for_each_changed_file(cwd, f),
#[cfg(feature = "git")]
- Self::Git => git::for_each_changed_file(cwd, f),
- Self::None => bail!("No diff support compiled in"),
+ Self::Git(inner) => inner.for_each_changed_file(cwd, f),
}
}
}