forked from gentoo-utils/gentoo-utils
put version and version operator in the same Option in the Atom struct
All atoms must either have a version with a version operator, or have no version and no version operator. Putting these in the same Option helps encode that into the type system.
This commit is contained in:
@@ -106,15 +106,23 @@ pub struct UseDep {
|
|||||||
#[derive(Clone, Debug, Get)]
|
#[derive(Clone, Debug, Get)]
|
||||||
pub struct Atom {
|
pub struct Atom {
|
||||||
blocker: Option<Blocker>,
|
blocker: Option<Blocker>,
|
||||||
version_operator: Option<VersionOperator>,
|
|
||||||
category: Category,
|
category: Category,
|
||||||
name: Name,
|
name: Name,
|
||||||
version: Option<Version>,
|
version: Option<(VersionOperator, Version)>,
|
||||||
slot: Option<Slot>,
|
slot: Option<Slot>,
|
||||||
#[get(kind = "deref")]
|
#[get(kind = "deref")]
|
||||||
usedeps: Vec<UseDep>,
|
usedeps: Vec<UseDep>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Atom {
|
||||||
|
pub fn version_operator(&self) -> Option<VersionOperator> {
|
||||||
|
match self.version {
|
||||||
|
Some((operator, _)) => Some(operator),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Blocker {
|
impl fmt::Display for Blocker {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
@@ -299,7 +307,7 @@ impl fmt::Display for Atom {
|
|||||||
write!(f, "{blocker}")?;
|
write!(f, "{blocker}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(version_operator) = self.version_operator.as_ref() {
|
if let Some(version_operator) = self.version_operator().as_ref() {
|
||||||
write!(f, "{version_operator}")?;
|
write!(f, "{version_operator}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +315,7 @@ impl fmt::Display for Atom {
|
|||||||
write!(f, "/")?;
|
write!(f, "/")?;
|
||||||
write!(f, "{}", self.name)?;
|
write!(f, "{}", self.name)?;
|
||||||
|
|
||||||
if let Some(version) = self.version.as_ref() {
|
if let Some((_, version)) = self.version.as_ref() {
|
||||||
write!(f, "-{version}")?;
|
write!(f, "-{version}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -253,36 +253,52 @@ impl<'a> Parseable<'a, &'a str> for Atom {
|
|||||||
type Parser = impl Parser<&'a str, Output = Self>;
|
type Parser = impl Parser<&'a str, Output = Self>;
|
||||||
|
|
||||||
fn parser() -> Self::Parser {
|
fn parser() -> Self::Parser {
|
||||||
Blocker::parser()
|
let usedeps = || {
|
||||||
.opt()
|
|
||||||
.and(VersionOperator::parser().opt())
|
|
||||||
.and(Category::parser())
|
|
||||||
.and(Name::parser().preceded_by(tag("/")))
|
|
||||||
.and(Version::parser().preceded_by(tag("-")).opt())
|
|
||||||
.and(Slot::parser().preceded_by(tag(":")).opt())
|
|
||||||
.and(
|
|
||||||
UseDep::parser()
|
UseDep::parser()
|
||||||
.separated_by(tag(","))
|
.separated_by(tag(","))
|
||||||
.many()
|
.many()
|
||||||
.delimited_by(tag("["), tag("]"))
|
.delimited_by(tag("["), tag("]"))
|
||||||
.opt(),
|
.opt()
|
||||||
)
|
};
|
||||||
|
|
||||||
|
let without_version = Blocker::parser()
|
||||||
|
.opt()
|
||||||
|
.and(Category::parser())
|
||||||
|
.and(Name::parser().preceded_by(tag("/")))
|
||||||
|
.and(Slot::parser().preceded_by(tag(":")).opt())
|
||||||
|
.and(usedeps())
|
||||||
|
.map(|((((blocker, category), name), slot), usedeps)| Atom {
|
||||||
|
blocker,
|
||||||
|
category,
|
||||||
|
name,
|
||||||
|
version: None,
|
||||||
|
slot,
|
||||||
|
usedeps: usedeps.unwrap_or(Vec::new()),
|
||||||
|
});
|
||||||
|
|
||||||
|
let with_version = Blocker::parser()
|
||||||
|
.opt()
|
||||||
|
.and(VersionOperator::parser())
|
||||||
|
.and(Category::parser())
|
||||||
|
.and(Name::parser().preceded_by(tag("/")))
|
||||||
|
.and(Version::parser().preceded_by(tag("-")))
|
||||||
|
.and(Slot::parser().preceded_by(tag(":")).opt())
|
||||||
|
.and(usedeps())
|
||||||
.map(
|
.map(
|
||||||
|((((((blocker, version_operator), category), name), version), slot), usedeps)| {
|
|((((((blocker, version_operator), category), name), version), slot), usedeps)| {
|
||||||
Atom {
|
Atom {
|
||||||
blocker,
|
blocker,
|
||||||
version_operator,
|
|
||||||
category,
|
category,
|
||||||
name,
|
name,
|
||||||
version,
|
version: Some((version_operator, version)),
|
||||||
slot,
|
slot,
|
||||||
usedeps: usedeps.unwrap_or(Vec::new()),
|
usedeps: usedeps.unwrap_or(Vec::new()),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.verify_output(|atom| match (&atom.version_operator, &atom.version) {
|
.verify_output(|atom| match &atom.version {
|
||||||
(Some(VersionOperator::Eq), Some(_)) => true,
|
Some((VersionOperator::Eq, _)) => true,
|
||||||
(Some(_), Some(version))
|
Some((_, version))
|
||||||
if !version
|
if !version
|
||||||
.numbers()
|
.numbers()
|
||||||
.iter()
|
.iter()
|
||||||
@@ -290,9 +306,10 @@ impl<'a> Parseable<'a, &'a str> for Atom {
|
|||||||
{
|
{
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
(None, None) => true,
|
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
});
|
||||||
|
|
||||||
|
with_version.or(without_version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user