pub use gix_config::*;use gix_features::threading::OnceCell; use crate::{Repository, bstr::BString, repository::identity}; pub(crate) mod cache;mod snapshot;#[cfg(feature = "credentials")]pub use snapshot::credential_helpers; ///pub mod overrides; pub mod tree;pub use tree::root::Tree; /// A platform to access configuration values as read from disk.////// Note that these values won't update even if the underlying file(s) change.pub struct Snapshot<'repo> { /// The owning repository. pub repo: &'repo Repository,} /// A platform to access configuration values and modify them in memory, while making them available when this platform is dropped/// as form of auto-commit./// Note that the values will only affect this instance of the parent repository, and not other clones that may exist.////// Note that these values won't update even if the underlying file(s) change.////// Use [`forget()`][Self::forget()] to not apply any of the changes.// TODO: make it possible to load snapshots with reloading via .config() and write mutated snapshots back to disk which should be the way// to affect all instances of a repo, probably via `config_mut()` and `config_mut_at()`.pub struct SnapshotMut<'repo> { /// The owning repository. pub repo: Option<&'repo mut Repository>, pub(crate) config: gix_config::File,} /// A utility structure created by [`SnapshotMut::commit_auto_rollback()`] that restores the previous configuration on drop.pub struct CommitAutoRollback<'repo> { /// The owning repository. pub repo: Option<&'repo mut Repository>, pub(crate) prev_config: crate::Config,} ///pub mod section { /// A filter that returns `true` for `meta` if the meta-data attached to a configuration section can be trusted. /// This is either the case if its file is fully trusted, or if it's a section from a system-wide file. pub fn is_trusted(meta: &gix_config::file::Metadata) -> bool { meta.trust == gix_sec::Trust::Full || meta.source.kind() != gix_config::source::Kind::Repository }} ///pub mod set_value { /// The error produced when calling [`SnapshotMut::set(_subsection)?_value()`][crate::config::SnapshotMut::set_value()] #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] SetRaw(#[from] gix_config::file::set_raw_value::Error), #[error(transparent)] Validate(#[from] crate::config::tree::key::validate::Error), #[error("The key needs a subsection parameter to be valid.")] SubSectionRequired, #[error("The key must not be used with a subsection")] SubSectionForbidden, }} /// The error returned when failing to initialize the repository configuration.////// This configuration is on the critical path when opening a repository.#[derive(Debug, thiserror::Error)]#[expect(missing_docs)]pub enum Error { #[error(transparent)] ConfigBoolean(#[from] boolean::Error), #[error(transparent)] ConfigUnsigned(#[from] unsigned_integer::Error), #[error(transparent)] ConfigTypedString(#[from] key::GenericErrorWithValue), #[error(transparent)] ConfigCompression(#[from] key::GenericError), #[error(transparent)] RefsNamespace(#[from] refs_namespace::Error), #[error("Cannot handle objects formatted as {:?}", .name)] UnsupportedObjectFormat { name: BString }, #[error( "extensions.objectFormat is a v1-only extension, but the repository format version is 0; \ set core.repositoryFormatVersion=1 to use it, or remove extensions.objectFormat to fall back to the default Sha1 format (if supported by this build)" )] ObjectFormatRequiresV1, #[error("Unsupported repository format version {version}; only versions 0 and 1 are supported")] UnsupportedRepositoryFormatVersion { version: usize }, #[error(transparent)] CoreAbbrev(#[from] abbrev::Error), #[error("Could not read configuration file at \"{}\"", path.display())] Io { source: std::io::Error, path: std::path::PathBuf, }, #[error(transparent)] Init(#[from] gix_config::file::init::Error), #[error(transparent)] ResolveIncludes(#[from] gix_config::file::includes::Error), #[error(transparent)] Span(#[from] gix_config::parse::span::Error), #[error(transparent)] ConfigValue(#[from] gix_config::file::section::value::Error), #[error(transparent)] FromEnv(#[from] gix_config::file::init::from_env::Error), #[error("The path {path:?} at the 'core.worktree' configuration could not be interpolated")] PathInterpolation { path: BString, source: gix_config::path::interpolate::Error, }, #[error("{source:?} configuration overrides at open or init time could not be applied.")] ConfigOverrides { #[source] err: overrides::Error, source: gix_config::Source, },} ///pub mod merge { /// pub mod pipeline_options { /// The error produced when obtaining options needed to fill in [gix_merge::blob::pipeline::Options]. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] BigFileThreshold(#[from] crate::config::unsigned_integer::Error), } } /// pub mod drivers { /// The error produced when obtaining a list of [Drivers](gix_merge::blob::Driver). #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] ConfigBoolean(#[from] crate::config::boolean::Error), } }} ///pub mod diff { /// pub mod algorithm { use crate::bstr::BString; /// The error produced when obtaining `diff.algorithm`. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error("Unknown diff algorithm named '{name}'")] Unknown { name: BString }, #[error("The '{name}' algorithm is not yet implemented")] Unimplemented { name: BString }, } } /// pub mod pipeline_options { /// The error produced when obtaining options needed to fill in [gix_diff::blob::pipeline::Options]. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] FilesystemCapabilities(#[from] crate::config::boolean::Error), #[error(transparent)] BigFileThreshold(#[from] crate::config::unsigned_integer::Error), } } /// pub mod drivers { use crate::bstr::BString; /// The error produced when obtaining a list of [Drivers](gix_diff::blob::Driver). #[derive(Debug, thiserror::Error)] #[error("Failed to parse value of 'diff.{name}.{attribute}'")] pub struct Error { /// The name of the driver. pub name: BString, /// The name of the attribute we tried to parse. pub attribute: &'static str, /// The actual error that occurred. pub source: Box<dyn std::error::Error + Send + Sync + 'static>, } }} ///pub mod stat_options { /// The error produced when collecting stat information, and returned by [Repository::stat_options()](crate::Repository::stat_options()). #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] ConfigCheckStat(#[from] super::key::GenericErrorWithValue), #[error(transparent)] ConfigBoolean(#[from] super::boolean::Error), }} ///#[cfg(feature = "attributes")]pub mod checkout_options { /// The error produced when collecting all information needed for checking out files into a worktree. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] ConfigCheckStat(#[from] super::key::GenericErrorWithValue), #[error(transparent)] ConfigBoolean(#[from] super::boolean::Error), #[error(transparent)] CheckoutWorkers(#[from] super::checkout::workers::Error), #[error(transparent)] Attributes(#[from] super::attribute_stack::Error), #[error(transparent)] FilterPipelineOptions(#[from] crate::filter::pipeline::options::Error), #[error(transparent)] CommandContext(#[from] crate::config::command_context::Error), }} ///#[cfg(feature = "attributes")]pub mod command_context { use crate::config; /// The error produced when collecting all information relevant to spawned commands, /// obtained via [Repository::command_context()](crate::Repository::command_context()). #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] Boolean(#[from] config::boolean::Error), #[error(transparent)] ParseBool(#[from] gix_config::value::Error), }} ///pub mod exclude_stack { use crate::config; use std::path::PathBuf; /// The error produced when setting up a stack to query `gitignore` information. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error("Could not read repository exclude")] Io(#[from] std::io::Error), #[error(transparent)] EnvironmentPermission(#[from] gix_sec::permission::Error<PathBuf>), #[error("The value for `core.excludesFile` could not be read from configuration")] ExcludesFilePathInterpolation(#[from] gix_config::path::interpolate::Error), #[error(transparent)] ParsePreciousEnabled(#[from] config::boolean::Error), }} ///pub mod attribute_stack { /// The error produced when setting up the attribute stack to query `gitattributes`. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error("An attribute file could not be read")] Io(#[from] std::io::Error), #[error("Failed to interpolate the attribute file configured at `core.attributesFile`")] AttributesFileInterpolation(#[from] gix_config::path::interpolate::Error), }} ///pub mod protocol { /// pub mod allow { use crate::bstr::BString; /// The error returned when obtaining the permission for a particular scheme. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] #[error("The value {value:?} must be allow|deny|user in configuration key protocol{0}.allow", scheme.as_ref().map(|s| format!(".{s}")).unwrap_or_default())] pub struct Error { pub scheme: Option<String>, pub value: BString, } }} ///pub mod ssh_connect_options { /// The error produced when obtaining ssh connection configuration. #[derive(Debug, thiserror::Error)] #[error(transparent)] pub struct Error(#[from] super::key::GenericErrorWithValue);} ///pub mod key { use crate::bstr::BString; const fn prefix(kind: char) -> &'static str { match kind { 'n' => "", // nothing 'k' => "The value of key", // generic key 't' => "The date format at key", // time 'i' => "The timeout at key", // timeout 'd' => "The duration [ms] at key", // duration 'b' => "The boolean at key", // boolean 'v' => "The key", // generic key with value 'r' => "The refspec at", // refspec 's' => "The ssl version at", // ssl-version 'u' => "The url at", // url 'w' => "The utf-8 string at", // string _ => panic!("BUG: invalid prefix kind - add a case for it here"), } } const fn suffix(kind: char) -> &'static str { match kind { 'd' => "could not be decoded", // decoding 'i' => "was invalid", // invalid 'u' => "could not be parsed as unsigned integer", // unsigned integer 'p' => "could not be parsed", // parsing _ => panic!("BUG: invalid suffix kind - add a case for it here"), } } /// A generic error suitable to produce decent messages for all kinds of configuration errors with config-key granularity. /// /// This error is meant to be reusable and help produce uniform error messages related to parsing any configuration key. #[derive(Debug, thiserror::Error)] #[error("{} \"{key}{}\"{} {}", prefix(PREFIX), value.as_ref().map(|v| format!("={v}")).unwrap_or_default(), environment_override.as_deref().map(|var| format!(" (possibly from {var})")).unwrap_or_default(), suffix(SUFFIX))] pub struct Error<E: std::error::Error + Send + Sync + 'static, const PREFIX: char, const SUFFIX: char> { /// The configuration key that contained the value. pub key: BString, /// The value that was assigned to `key`. pub value: Option<BString>, /// The associated environment variable that would override this value. pub environment_override: Option<&'static str>, /// The source of the error if there was one. pub source: Option<E>, } /// Initialization /// Instantiate a new error from the given `key`. /// /// Note that specifics of the error message are defined by the `PREFIX` and `SUFFIX` which is usually defined by a typedef. impl<T, E, const PREFIX: char, const SUFFIX: char> From<&'static T> for Error<E, PREFIX, SUFFIX> where E: std::error::Error + Send + Sync + 'static, T: super::tree::Key, { fn from(key: &'static T) -> Self { Error { key: key.logical_name().into(), value: None, environment_override: key.environment_override(), source: None, } } } /// Initialization impl<E, const PREFIX: char, const SUFFIX: char> Error<E, PREFIX, SUFFIX> where E: std::error::Error + Send + Sync + 'static, { /// Instantiate an error with all data from `key` along with the `value` of the key. pub fn from_value(key: &'static impl super::tree::Key, value: BString) -> Self { Error::from(key).with_value(value) } } /// Builder impl<E, const PREFIX: char, const SUFFIX: char> Error<E, PREFIX, SUFFIX> where E: std::error::Error + Send + Sync + 'static, { /// Attach the given `err` as source. pub fn with_source(mut self, err: E) -> Self { self.source = Some(err); self } /// Attach the given `value` as value we observed when the error was produced. pub fn with_value(mut self, value: BString) -> Self { self.value = Some(value); self } } /// A generic key error for use when it doesn't seem worth it say more than 'key is invalid' along with meta-data. pub type GenericError<E = gix_config::value::Error> = Error<E, 'k', 'i'>; /// A generic key error which will also contain a value. pub type GenericErrorWithValue<E = gix_config::value::Error> = Error<E, 'v', 'i'>;} ///pub mod encoding { use crate::bstr::BString; /// The error produced when failing to parse the `core.checkRoundTripEncoding` key. #[derive(Debug, thiserror::Error)] #[error("The encoding named '{encoding}' seen in key '{key}={value}' is unsupported")] pub struct Error { /// The configuration key that contained the value. pub key: BString, /// The value that was assigned to `key`. pub value: BString, /// The encoding that failed. pub encoding: BString, }} ///pub mod checkout { /// pub mod workers { use crate::config; /// The error produced when failing to parse the `checkout.workers` key. pub type Error = config::key::Error<gix_config::value::Error, 'n', 'd'>; }} ///pub mod abbrev { use crate::bstr::BString; /// The error describing an incorrect `core.abbrev` value. #[derive(Debug, thiserror::Error)] #[error("Invalid value for 'core.abbrev' = '{}'. It must be between 4 and {}", .value, .max)] pub struct Error { /// The value found in the git configuration pub value: BString, /// The maximum abbreviation length, the length of an object hash. pub max: u8, }} ///pub mod remote { /// pub mod symbolic_name { /// The error produced when failing to produce a symbolic remote name from configuration. pub type Error = super::super::key::Error<crate::remote::name::Error, 'v', 'i'>; }} ///pub mod time { /// The error produced when failing to parse time from configuration. pub type Error = super::key::Error<gix_date::Error, 't', 'i'>;} ///pub mod commit_signature { /// The error produced when obtaining or installing a fallback commit signature. #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] pub enum Error { #[error(transparent)] Time(#[from] super::time::Error), #[error(transparent)] Span(#[from] gix_config::parse::span::Error), }} ///pub mod lock_timeout { /// The error produced when failing to parse timeout for locks. pub type Error = super::key::Error<gix_config::value::Error, 'i', 'i'>;} ///pub mod duration { /// The error produced when failing to parse durations (in milliseconds). pub type Error = super::key::Error<gix_config::value::Error, 'd', 'i'>;} ///pub mod boolean { /// The error produced when failing to parse time from configuration. pub type Error = super::key::Error<gix_config::value::Error, 'b', 'i'>;} ///Lines 1–500 of 682. Load more
pub use gix_config::*; use gix_features::threading::OnceCell; use crate::{Repository, bstr::BString, repository::identity}; pub(crate) mod cache; mod snapshot; #[cfg(feature = "credentials")] pub use snapshot::credential_helpers; /// pub mod overrides; pub mod tree; pub use tree::root::Tree; /// A platform to access configuration values as read from disk. /// /// Note that these values won't update even if the underlying file(s) change. pub struct Snapshot<'repo> { /// The owning repository. pub repo: &'repo Repository, } /// A platform to access configuration values and modify them in memory, while making them available when this platform is dropped /// as form of auto-commit. /// Note that the values will only affect this instance of the parent repository, and not other clones that may exist. /// /// Note that these values won't update even if the underlying file(s) change. /// /// Use [`forget()`][Self::forget()] to not apply any of the changes. // TODO: make it possible to load snapshots with reloading via .config() and write mutated snapshots back to disk which should be the way // to affect all instances of a repo, probably via `config_mut()` and `config_mut_at()`. pub struct SnapshotMut<'repo> { /// The owning repository. pub repo: Option<&'repo mut Repository>, pub(crate) config: gix_config::File, } /// A utility structure created by [`SnapshotMut::commit_auto_rollback()`] that restores the previous configuration on drop. pub struct CommitAutoRollback<'repo> { /// The owning repository. pub repo: Option<&'repo mut Repository>, pub(crate) prev_config: crate::Config, } /// pub mod section { /// A filter that returns `true` for `meta` if the meta-data attached to a configuration section can be trusted. /// This is either the case if its file is fully trusted, or if it's a section from a system-wide file. pub fn is_trusted(meta: &gix_config::file::Metadata) -> bool { meta.trust == gix_sec::Trust::Full || meta.source.kind() != gix_config::source::Kind::Repository } } /// pub mod set_value { /// The error produced when calling [`SnapshotMut::set(_subsection)?_value()`][crate::config::SnapshotMut::set_value()] #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] SetRaw(#[from] gix_config::file::set_raw_value::Error), #[error(transparent)] Validate(#[from] crate::config::tree::key::validate::Error), #[error("The key needs a subsection parameter to be valid.")] SubSectionRequired, #[error("The key must not be used with a subsection")] SubSectionForbidden, } } /// The error returned when failing to initialize the repository configuration. /// /// This configuration is on the critical path when opening a repository. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] ConfigBoolean(#[from] boolean::Error), #[error(transparent)] ConfigUnsigned(#[from] unsigned_integer::Error), #[error(transparent)] ConfigTypedString(#[from] key::GenericErrorWithValue), #[error(transparent)] ConfigCompression(#[from] key::GenericError), #[error(transparent)] RefsNamespace(#[from] refs_namespace::Error), #[error("Cannot handle objects formatted as {:?}", .name)] UnsupportedObjectFormat { name: BString }, #[error( "extensions.objectFormat is a v1-only extension, but the repository format version is 0; \ set core.repositoryFormatVersion=1 to use it, or remove extensions.objectFormat to fall back to the default Sha1 format (if supported by this build)" )] ObjectFormatRequiresV1, #[error("Unsupported repository format version {version}; only versions 0 and 1 are supported")] UnsupportedRepositoryFormatVersion { version: usize }, #[error(transparent)] CoreAbbrev(#[from] abbrev::Error), #[error("Could not read configuration file at \"{}\"", path.display())] Io { source: std::io::Error, path: std::path::PathBuf, }, #[error(transparent)] Init(#[from] gix_config::file::init::Error), #[error(transparent)] ResolveIncludes(#[from] gix_config::file::includes::Error), #[error(transparent)] Span(#[from] gix_config::parse::span::Error), #[error(transparent)] ConfigValue(#[from] gix_config::file::section::value::Error), #[error(transparent)] FromEnv(#[from] gix_config::file::init::from_env::Error), #[error("The path {path:?} at the 'core.worktree' configuration could not be interpolated")] PathInterpolation { path: BString, source: gix_config::path::interpolate::Error, }, #[error("{source:?} configuration overrides at open or init time could not be applied.")] ConfigOverrides { #[source] err: overrides::Error, source: gix_config::Source, }, } /// pub mod merge { /// pub mod pipeline_options { /// The error produced when obtaining options needed to fill in [gix_merge::blob::pipeline::Options]. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] BigFileThreshold(#[from] crate::config::unsigned_integer::Error), } } /// pub mod drivers { /// The error produced when obtaining a list of [Drivers](gix_merge::blob::Driver). #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] ConfigBoolean(#[from] crate::config::boolean::Error), } } } /// pub mod diff { /// pub mod algorithm { use crate::bstr::BString; /// The error produced when obtaining `diff.algorithm`. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error("Unknown diff algorithm named '{name}'")] Unknown { name: BString }, #[error("The '{name}' algorithm is not yet implemented")] Unimplemented { name: BString }, } } /// pub mod pipeline_options { /// The error produced when obtaining options needed to fill in [gix_diff::blob::pipeline::Options]. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] FilesystemCapabilities(#[from] crate::config::boolean::Error), #[error(transparent)] BigFileThreshold(#[from] crate::config::unsigned_integer::Error), } } /// pub mod drivers { use crate::bstr::BString; /// The error produced when obtaining a list of [Drivers](gix_diff::blob::Driver). #[derive(Debug, thiserror::Error)] #[error("Failed to parse value of 'diff.{name}.{attribute}'")] pub struct Error { /// The name of the driver. pub name: BString, /// The name of the attribute we tried to parse. pub attribute: &'static str, /// The actual error that occurred. pub source: Box<dyn std::error::Error + Send + Sync + 'static>, } } } /// pub mod stat_options { /// The error produced when collecting stat information, and returned by [Repository::stat_options()](crate::Repository::stat_options()). #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] ConfigCheckStat(#[from] super::key::GenericErrorWithValue), #[error(transparent)] ConfigBoolean(#[from] super::boolean::Error), } } /// #[cfg(feature = "attributes")] pub mod checkout_options { /// The error produced when collecting all information needed for checking out files into a worktree. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] ConfigCheckStat(#[from] super::key::GenericErrorWithValue), #[error(transparent)] ConfigBoolean(#[from] super::boolean::Error), #[error(transparent)] CheckoutWorkers(#[from] super::checkout::workers::Error), #[error(transparent)] Attributes(#[from] super::attribute_stack::Error), #[error(transparent)] FilterPipelineOptions(#[from] crate::filter::pipeline::options::Error), #[error(transparent)] CommandContext(#[from] crate::config::command_context::Error), } } /// #[cfg(feature = "attributes")] pub mod command_context { use crate::config; /// The error produced when collecting all information relevant to spawned commands, /// obtained via [Repository::command_context()](crate::Repository::command_context()). #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error(transparent)] Boolean(#[from] config::boolean::Error), #[error(transparent)] ParseBool(#[from] gix_config::value::Error), } } /// pub mod exclude_stack { use crate::config; use std::path::PathBuf; /// The error produced when setting up a stack to query `gitignore` information. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error("Could not read repository exclude")] Io(#[from] std::io::Error), #[error(transparent)] EnvironmentPermission(#[from] gix_sec::permission::Error<PathBuf>), #[error("The value for `core.excludesFile` could not be read from configuration")] ExcludesFilePathInterpolation(#[from] gix_config::path::interpolate::Error), #[error(transparent)] ParsePreciousEnabled(#[from] config::boolean::Error), } } /// pub mod attribute_stack { /// The error produced when setting up the attribute stack to query `gitattributes`. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] pub enum Error { #[error("An attribute file could not be read")] Io(#[from] std::io::Error), #[error("Failed to interpolate the attribute file configured at `core.attributesFile`")] AttributesFileInterpolation(#[from] gix_config::path::interpolate::Error), } } /// pub mod protocol { /// pub mod allow { use crate::bstr::BString; /// The error returned when obtaining the permission for a particular scheme. #[derive(Debug, thiserror::Error)] #[expect(missing_docs)] #[error("The value {value:?} must be allow|deny|user in configuration key protocol{0}.allow", scheme.as_ref().map(|s| format!(".{s}")).unwrap_or_default())] pub struct Error { pub scheme: Option<String>, pub value: BString, } } } /// pub mod ssh_connect_options { /// The error produced when obtaining ssh connection configuration. #[derive(Debug, thiserror::Error)] #[error(transparent)] pub struct Error(#[from] super::key::GenericErrorWithValue); } /// pub mod key { use crate::bstr::BString; const fn prefix(kind: char) -> &'static str { match kind { 'n' => "", // nothing 'k' => "The value of key", // generic key 't' => "The date format at key", // time 'i' => "The timeout at key", // timeout 'd' => "The duration [ms] at key", // duration 'b' => "The boolean at key", // boolean 'v' => "The key", // generic key with value 'r' => "The refspec at", // refspec 's' => "The ssl version at", // ssl-version 'u' => "The url at", // url 'w' => "The utf-8 string at", // string _ => panic!("BUG: invalid prefix kind - add a case for it here"), } } const fn suffix(kind: char) -> &'static str { match kind { 'd' => "could not be decoded", // decoding 'i' => "was invalid", // invalid 'u' => "could not be parsed as unsigned integer", // unsigned integer 'p' => "could not be parsed", // parsing _ => panic!("BUG: invalid suffix kind - add a case for it here"), } } /// A generic error suitable to produce decent messages for all kinds of configuration errors with config-key granularity. /// /// This error is meant to be reusable and help produce uniform error messages related to parsing any configuration key. #[derive(Debug, thiserror::Error)] #[error("{} \"{key}{}\"{} {}", prefix(PREFIX), value.as_ref().map(|v| format!("={v}")).unwrap_or_default(), environment_override.as_deref().map(|var| format!(" (possibly from {var})")).unwrap_or_default(), suffix(SUFFIX))] pub struct Error<E: std::error::Error + Send + Sync + 'static, const PREFIX: char, const SUFFIX: char> { /// The configuration key that contained the value. pub key: BString, /// The value that was assigned to `key`. pub value: Option<BString>, /// The associated environment variable that would override this value. pub environment_override: Option<&'static str>, /// The source of the error if there was one. pub source: Option<E>, } /// Initialization /// Instantiate a new error from the given `key`. /// /// Note that specifics of the error message are defined by the `PREFIX` and `SUFFIX` which is usually defined by a typedef. impl<T, E, const PREFIX: char, const SUFFIX: char> From<&'static T> for Error<E, PREFIX, SUFFIX> where E: std::error::Error + Send + Sync + 'static, T: super::tree::Key, { fn from(key: &'static T) -> Self { Error { key: key.logical_name().into(), value: None, environment_override: key.environment_override(), source: None, } } } /// Initialization impl<E, const PREFIX: char, const SUFFIX: char> Error<E, PREFIX, SUFFIX> where E: std::error::Error + Send + Sync + 'static, { /// Instantiate an error with all data from `key` along with the `value` of the key. pub fn from_value(key: &'static impl super::tree::Key, value: BString) -> Self { Error::from(key).with_value(value) } } /// Builder impl<E, const PREFIX: char, const SUFFIX: char> Error<E, PREFIX, SUFFIX> where E: std::error::Error + Send + Sync + 'static, { /// Attach the given `err` as source. pub fn with_source(mut self, err: E) -> Self { self.source = Some(err); self } /// Attach the given `value` as value we observed when the error was produced. pub fn with_value(mut self, value: BString) -> Self { self.value = Some(value); self } } /// A generic key error for use when it doesn't seem worth it say more than 'key is invalid' along with meta-data. pub type GenericError<E = gix_config::value::Error> = Error<E, 'k', 'i'>; /// A generic key error which will also contain a value. pub type GenericErrorWithValue<E = gix_config::value::Error> = Error<E, 'v', 'i'>; } /// pub mod encoding { use crate::bstr::BString; /// The error produced when failing to parse the `core.checkRoundTripEncoding` key. #[derive(Debug, thiserror::Error)] #[error("The encoding named '{encoding}' seen in key '{key}={value}' is unsupported")] pub struct Error { /// The configuration key that contained the value. pub key: BString, /// The value that was assigned to `key`. pub value: BString, /// The encoding that failed. pub encoding: BString, } } /// pub mod checkout { /// pub mod workers { use crate::config; /// The error produced when failing to parse the `checkout.workers` key. pub type Error = config::key::Error<gix_config::value::Error, 'n', 'd'>; } } /// pub mod abbrev { use crate::bstr::BString; /// The error describing an incorrect `core.abbrev` value. #[derive(Debug, thiserror::Error)] #[error("Invalid value for 'core.abbrev' = '{}'. It must be between 4 and {}", .value, .max)] pub struct Error { /// The value found in the git configuration pub value: BString, /// The maximum abbreviation length, the length of an object hash. pub max: u8, } } /// pub mod remote { /// pub mod symbolic_name { /// The error produced when failing to produce a symbolic remote name from configuration. pub type Error = super::super::key::Error<crate::remote::name::Error, 'v', 'i'>; } } /// pub mod time { /// The error produced when failing to parse time from configuration. pub type Error = super::key::Error<gix_date::Error, 't', 'i'>; } /// pub mod commit_signature { /// The error produced when obtaining or installing a fallback commit signature. #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] pub enum Error { #[error(transparent)] Time(#[from] super::time::Error), #[error(transparent)] Span(#[from] gix_config::parse::span::Error), } } /// pub mod lock_timeout { /// The error produced when failing to parse timeout for locks. pub type Error = super::key::Error<gix_config::value::Error, 'i', 'i'>; } /// pub mod duration { /// The error produced when failing to parse durations (in milliseconds). pub type Error = super::key::Error<gix_config::value::Error, 'd', 'i'>; } /// pub mod boolean { /// The error produced when failing to parse time from configuration. pub type Error = super::key::Error<gix_config::value::Error, 'b', 'i'>; } ///