use crate::{manifest::Alias, ser_display_deser_fromstr, source::specifiers::DependencySpecifiers};
use serde::{Deserialize, Serialize};
use std::{
fmt::{Display, Formatter},
str::FromStr,
};
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct OverrideKey(pub Vec<Vec<Alias>>);
ser_display_deser_fromstr!(OverrideKey);
impl FromStr for OverrideKey {
type Err = errors::OverrideKeyFromStr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let overrides = s
.split(',')
.map(|overrides| {
overrides
.split('>')
.map(Alias::from_str)
.collect::<Result<_, _>>()
})
.collect::<Result<Vec<Vec<Alias>>, _>>()?;
if overrides.is_empty() {
return Err(errors::OverrideKeyFromStr::Empty);
}
Ok(Self(overrides))
}
}
#[cfg(test)]
impl schemars::JsonSchema for OverrideKey {
fn schema_name() -> std::borrow::Cow<'static, str> {
"OverrideKey".into()
}
fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
schemars::json_schema!({
"type": "string",
"pattern": r"^(?:[a-zA-Z0-9_-]+>[a-zA-Z0-9_-]+(?:>[a-zA-Z0-9_-]+)*)(?:,(?:[a-zA-Z0-9_-]+>[a-zA-Z0-9_-]+(?:>[a-zA-Z0-9_-]+)*))*$",
})
}
}
impl Display for OverrideKey {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
self.0
.iter()
.map(|overrides| {
overrides
.iter()
.map(Alias::as_str)
.collect::<Vec<_>>()
.join(">")
})
.collect::<Vec<_>>()
.join(",")
)
}
}
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(test, derive(schemars::JsonSchema))]
#[serde(untagged)]
pub enum OverrideSpecifier {
Specifier(DependencySpecifiers),
Alias(Alias),
}
pub mod errors {
use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum OverrideKeyFromStr {
#[error("empty override key")]
Empty,
#[error("invalid alias in override key")]
InvalidAlias(#[from] crate::manifest::errors::AliasFromStr),
}
}