use crate::{
config,
config::tree::{Key, Protocol, Section, keys},
};
impl Protocol {
pub const ALLOW: Allow = Allow::new_with_validate("allow", &config::Tree::PROTOCOL, validate::Allow);
pub const VERSION: Version = Version::new_with_validate("version", &config::Tree::PROTOCOL, validate::Version);
pub const NAME_PARAMETER: NameParameter = NameParameter;
}
pub type Allow = keys::Any<validate::Allow>;
pub type Version = keys::Any<validate::Version>;
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
mod allow {
use crate::{Error, Result, bstr::ByteSlice, config::tree::protocol::Allow, remote::url::scheme_permission};
impl Allow {
pub fn try_into_allow(
&'static self,
value: impl gix_utils::AsBStr,
scheme: Option<&str>,
) -> Result<scheme_permission::Allow> {
let value = value.as_bstr();
scheme_permission::Allow::try_from(value.as_bstr()).map_err(|value| {
Error::from_error(gix_error::validation(format!(
"The value {value:?} must be allow|deny|user in configuration key protocol{}.allow",
scheme.map(|scheme| format!(".{scheme}")).unwrap_or_default()
)))
})
}
}
}
pub struct NameParameter;
impl NameParameter {
pub const ALLOW: Allow = Allow::new_with_validate("allow", &Protocol::NAME_PARAMETER, validate::Allow);
}
impl Section for NameParameter {
fn name(&self) -> &str {
"<name>"
}
fn keys(&self) -> &[&dyn Key] {
&[&Self::ALLOW]
}
fn parent(&self) -> Option<&dyn Section> {
Some(&config::Tree::PROTOCOL)
}
}
impl Section for Protocol {
fn name(&self) -> &str {
"protocol"
}
fn keys(&self) -> &[&dyn Key] {
&[&Self::ALLOW, &Self::VERSION]
}
fn sub_sections(&self) -> &[&dyn Section] {
&[&Self::NAME_PARAMETER]
}
}
mod key_impls {
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
use crate::{Error, ExnMessageResult, Result};
impl super::Version {
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
pub fn try_into_protocol_version(
&'static self,
value: ExnMessageResult<Option<i64>>,
) -> Result<gix_protocol::transport::Protocol> {
use gix_error::ResultExt;
let Some(value) = value.or_raise(|| crate::config::key::error(self, "Invalid protocol version"))? else {
return Ok(gix_protocol::transport::Protocol::V2);
};
Ok(match value {
0 => gix_protocol::transport::Protocol::V0,
1 => gix_protocol::transport::Protocol::V1,
2 => gix_protocol::transport::Protocol::V2,
other => {
return Err(Error::from_error(crate::config::key::error_with_value(
self,
"Invalid protocol version",
other,
)));
}
})
}
}
}
mod validate {
use crate::{ExnResult, bstr::BStr, config::tree::keys};
use gix_error::{ErrorExt, ResultExt, message};
#[derive(Clone, Copy)]
pub struct Allow;
impl keys::Validate for Allow {
fn validate(&self, _value: &BStr) -> ExnResult {
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client"))]
super::Protocol::ALLOW.try_into_allow(_value, None).or_erased()?;
Ok(())
}
}
#[derive(Clone, Copy)]
pub struct Version;
impl keys::Validate for Version {
fn validate(&self, value: &BStr) -> ExnResult {
let value = gix_config::Integer::try_from(value)
.or_erased()?
.to_decimal()
.ok_or_else(|| message!("integer {value} cannot be represented as integer").raise_erased())?;
match value {
0..=2 => Ok(()),
_ => Err(message!("protocol version {value} is unknown").raise_erased()),
}
}
}
}