use super::{
ArchConstraints, BuildProfileRestrictionFormula, Error, VersionConstraint, pest::Rule,
};
use crate::architecture::Architecture;
use pest::iterators::Pair;
#[derive(Clone, Debug, PartialEq, Default)]
pub struct Package {
pub name: String,
pub arch: Option<Architecture>,
pub version_constraint: Option<VersionConstraint>,
pub arch_constraints: Option<ArchConstraints>,
pub build_profile_restriction_formula: Option<BuildProfileRestrictionFormula>,
}
impl std::fmt::Display for Package {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}", self.name)?;
if let Some(arch) = &self.arch {
write!(f, ":{arch}")?;
}
if let Some(version_constraint) = &self.version_constraint {
write!(
f,
" ({} {})",
version_constraint.operator, version_constraint.version
)?;
}
if let Some(arch_constraints) = &self.arch_constraints {
write!(f, " [{arch_constraints}]")?;
}
if let Some(bprf) = &self.build_profile_restriction_formula {
for build_profile_constraints in &bprf.build_profile_constraints {
write!(f, " <{build_profile_constraints}>")?;
}
}
Ok(())
}
}
impl TryFrom<Pair<'_, Rule>> for Package {
type Error = Error;
fn try_from(token: Pair<'_, Rule>) -> Result<Self, Error> {
let mut ret = Package {
..Default::default()
};
for constraint in token.into_inner() {
match constraint.as_rule() {
Rule::package_name => ret.name = constraint.as_str().to_owned(),
Rule::arch_name => {
if ret.arch.is_some() {
return Err(Error::InvalidPackage);
}
ret.arch = Some(constraint.as_str().to_owned().parse()?)
}
Rule::version_constraint => {
if ret.version_constraint.is_some() {
return Err(Error::TooManyVersions);
}
ret.version_constraint = Some(constraint.try_into()?);
}
Rule::arch_constraints => {
if ret.arch_constraints.is_some() {
return Err(Error::TooManyArches);
}
ret.arch_constraints = Some(constraint.try_into()?);
}
Rule::build_profile_constraints => {
if ret.build_profile_restriction_formula.is_none() {
ret.build_profile_restriction_formula = Some(Default::default());
}
let Some(bprf) = &mut ret.build_profile_restriction_formula else {
unreachable!();
};
bprf.build_profile_constraints.push(constraint.try_into()?);
}
_ => continue,
};
}
Ok(ret)
}
}