use bstr::{BStr, BString, ByteSlice};
#[derive(Default, Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum Ignore {
All,
Dirty,
Untracked,
#[default]
None,
}
impl TryFrom<&BStr> for Ignore {
type Error = ();
fn try_from(value: &BStr) -> Result<Self, Self::Error> {
Ok(match value.as_bytes() {
b"all" => Ignore::All,
b"dirty" => Ignore::Dirty,
b"untracked" => Ignore::Untracked,
b"none" => Ignore::None,
_ => return Err(()),
})
}
}
#[derive(Default, Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum FetchRecurse {
#[default]
OnDemand,
Always,
Never,
}
impl FetchRecurse {
pub fn new(boolean: Result<bool, gix_config::value::Error>) -> Result<Self, BString> {
Ok(match boolean {
Ok(value) => {
if value {
FetchRecurse::Always
} else {
FetchRecurse::Never
}
}
Err(err) => {
if err.input != "on-demand" {
return Err(err.input);
}
FetchRecurse::OnDemand
}
})
}
}
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum Branch {
CurrentInSuperproject,
Name(BString),
}
impl Default for Branch {
fn default() -> Self {
Branch::Name("HEAD".into())
}
}
impl TryFrom<&BStr> for Branch {
type Error = gix_refspec::parse::Error;
fn try_from(value: &BStr) -> Result<Self, Self::Error> {
if value == "." {
return Ok(Branch::CurrentInSuperproject);
}
gix_refspec::parse(value, gix_refspec::parse::Operation::Fetch)
.map(|spec| Branch::Name(spec.source().expect("no object").to_owned()))
}
}
#[derive(Default, Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
pub enum Update {
#[default]
Checkout,
Rebase,
Merge,
Command(BString),
None,
}
impl TryFrom<&BStr> for Update {
type Error = ();
fn try_from(value: &BStr) -> Result<Self, Self::Error> {
Ok(match value.as_bstr().as_bytes() {
b"checkout" => Update::Checkout,
b"rebase" => Update::Rebase,
b"merge" => Update::Merge,
b"none" => Update::None,
command if command.first() == Some(&b'!') => Update::Command(command[1..].to_owned().into()),
_ => return Err(()),
})
}
}
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
#[error("The '{field}' field of submodule '{submodule}' was invalid: '{actual}'")]
pub struct Error {
pub field: &'static str,
pub submodule: BString,
pub actual: BString,
}
pub mod branch {
use bstr::BString;
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
#[error(
"The value '{actual}' of the 'branch' field of submodule '{submodule}' couldn't be turned into a valid fetch refspec"
)]
pub struct Error {
pub submodule: BString,
pub actual: BString,
pub source: gix_refspec::parse::Error,
}
}
pub mod update {
use bstr::BString;
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("The 'update' field of submodule '{submodule}' tried to set command '{actual}' to be shared")]
CommandForbiddenInModulesConfiguration { submodule: BString, actual: BString },
#[error("The 'update' field of submodule '{submodule}' was invalid: '{actual}'")]
Invalid { submodule: BString, actual: BString },
}
}
pub mod url {
use bstr::BString;
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("The url of submodule '{submodule}' could not be parsed")]
Parse {
submodule: BString,
source: gix_url::parse::Error,
},
#[error("The submodule '{submodule}' was missing its 'url' field or it was empty")]
Missing { submodule: BString },
}
}
pub mod path {
use bstr::BString;
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error("The path '{actual}' of submodule '{submodule}' needs to be relative")]
Absolute { actual: BString, submodule: BString },
#[error("The submodule '{submodule}' was missing its 'path' field or it was empty")]
Missing { submodule: BString },
#[error("The path '{actual}' would lead outside of the repository worktree")]
OutsideOfWorktree { actual: BString, submodule: BString },
}
}