rust: implement `From<SparseConfigWarning>` for `HgError`
authorRaphaël Gomès <rgomes@octobus.net>
Mon, 30 Sep 2024 16:55:11 +0200
changeset 52043 ae1ab6d71f4a
parent 52042 92e23ba257d1
child 52044 0cd16b1d613f
rust: implement `From<SparseConfigWarning>` for `HgError` This will be useful in a future patch to avoid a lot of boilerplate.
rust/hg-core/src/narrow.rs
rust/hg-core/src/sparse.rs
--- a/rust/hg-core/src/narrow.rs	Mon Sep 30 16:04:51 2024 +0200
+++ b/rust/hg-core/src/narrow.rs	Mon Sep 30 16:55:11 2024 +0200
@@ -24,7 +24,7 @@
 /// as part of wire protocol commands. That means that changes to this
 /// data structure influence the wire protocol and should not be taken
 /// lightly - especially removals.
-const VALID_PREFIXES: [&str; 2] = ["path:", "rootfilesin:"];
+pub const VALID_PREFIXES: [&str; 2] = ["path:", "rootfilesin:"];
 
 /// Return the matcher for the current narrow spec, and all configuration
 /// warnings to display.
--- a/rust/hg-core/src/sparse.rs	Mon Sep 30 16:04:51 2024 +0200
+++ b/rust/hg-core/src/sparse.rs	Mon Sep 30 16:55:11 2024 +0200
@@ -1,14 +1,16 @@
-use std::{collections::HashSet, path::Path};
+use std::{collections::HashSet, fmt::Display, path::Path};
 
-use format_bytes::{write_bytes, DisplayBytes};
+use format_bytes::{format_bytes, write_bytes, DisplayBytes};
 
 use crate::{
     errors::HgError,
+    exit_codes::STATE_ERROR,
     filepatterns::parse_pattern_file_contents,
     matchers::{
         AlwaysMatcher, DifferenceMatcher, IncludeMatcher, Matcher,
         UnionMatcher,
     },
+    narrow::VALID_PREFIXES,
     operations::cat,
     repo::Repo,
     requirements::SPARSE_REQUIREMENT,
@@ -36,6 +38,15 @@
     }
 }
 
+impl Display for SparseConfigContext {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            SparseConfigContext::Sparse => write!(f, "sparse"),
+            SparseConfigContext::Narrow => write!(f, "narrow"),
+        }
+    }
+}
+
 /// Possible warnings when reading sparse configuration
 #[derive(Debug, derive_more::From)]
 pub enum SparseWarning {
@@ -82,6 +93,59 @@
     PatternError(PatternError),
 }
 
+impl From<SparseConfigError> for HgError {
+    fn from(value: SparseConfigError) -> Self {
+        match value {
+            SparseConfigError::IncludesAfterExcludes { context } => {
+                HgError::Abort {
+                    message: format!(
+                        "{} config cannot have includes after excludes",
+                        context,
+                    ),
+                    detailed_exit_code: STATE_ERROR,
+                    hint: None,
+                }
+            }
+            SparseConfigError::EntryOutsideSection { context, line } => {
+                HgError::Abort {
+                    message: format!(
+                        "{} config entry outside of section: {}",
+                        context,
+                        String::from_utf8_lossy(&line)
+                    ),
+                    detailed_exit_code: STATE_ERROR,
+                    hint: None,
+                }
+            }
+            SparseConfigError::IncludesInNarrow => HgError::Abort {
+                message: "including other spec files using '%include' is not \
+                supported in narrowspec"
+                    .to_string(),
+                detailed_exit_code: STATE_ERROR,
+                hint: None,
+            },
+            SparseConfigError::InvalidNarrowPrefix(vec) => HgError::Abort {
+                message: String::from_utf8_lossy(&format_bytes!(
+                    b"invalid prefix on narrow pattern: {}",
+                    vec
+                ))
+                .to_string(),
+                detailed_exit_code: STATE_ERROR,
+                hint: Some(format!(
+                    "narrow patterns must begin with one of the following: {}",
+                    VALID_PREFIXES.join(", ")
+                )),
+            },
+            SparseConfigError::HgError(hg_error) => hg_error,
+            SparseConfigError::PatternError(pattern_error) => HgError::Abort {
+                message: pattern_error.to_string(),
+                detailed_exit_code: STATE_ERROR,
+                hint: None,
+            },
+        }
+    }
+}
+
 /// Parse sparse config file content.
 pub(crate) fn parse_config(
     raw: &[u8],