allow slot to be only :* := :slot/sub= or :slot

This commit is contained in:
John Turner
2025-11-18 04:15:53 +00:00
parent 2dc5df6112
commit c75a38f615
2 changed files with 41 additions and 28 deletions

View File

@@ -79,11 +79,17 @@ pub enum SlotOperator {
#[derive(Clone, Debug, PartialEq, Eq, Get)]
pub struct SlotName(#[get(method = "name", kind = "deref")] String);
#[derive(Clone, Debug, PartialEq, Eq, Get)]
pub struct Slot {
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Slot {
Wildcard,
Equal {
primary: Option<SlotName>,
sub: Option<SlotName>,
operator: Option<SlotOperator>,
},
Name {
primary: SlotName,
sub: Option<SlotName>,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -575,21 +581,31 @@ impl fmt::Display for SlotName {
impl fmt::Display for Slot {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(slot) = self.primary.as_ref() {
write!(f, "{slot}")?;
match self {
Self::Wildcard => write!(f, "*"),
Self::Equal { primary, sub } => {
if let Some(primary) = primary {
write!(f, "{primary}")?;
}
if let Some(sub) = self.sub.as_ref() {
if let Some(sub) = sub {
write!(f, "/{sub}")?;
}
if let Some(operator) = self.operator.as_ref() {
write!(f, "{operator}")?;
write!(f, "=")
}
Self::Name { primary, sub } => {
write!(f, "{primary}")?;
if let Some(sub) = sub {
write!(f, "/{sub}")?;
}
Ok(())
}
}
}
}
impl fmt::Display for UseDepNegate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

View File

@@ -186,21 +186,17 @@ impl<'a> Parseable<'a, &'a str> for Slot {
type Parser = impl Parser<&'a str, Output = Self>;
fn parser() -> Self::Parser {
SlotName::parser()
let wildcard = tag("*").map(|_| Slot::Wildcard);
let equals = SlotName::parser()
.opt()
.and(SlotName::parser().preceded_by(tag("/")).opt())
.and(SlotOperator::parser().opt())
.map(|((primary, sub), operator)| Slot {
primary,
sub,
operator,
})
.verify_output(|slot| {
matches!(
(&slot.primary(), &slot.operator()),
(Some(_) | None, Some(_)) | (Some(_), None)
)
})
.followed_by(tag("="))
.map(|(primary, sub)| Slot::Equal { primary, sub });
let name = SlotName::parser()
.and(SlotName::parser().preceded_by(tag("/")).opt())
.map(|(primary, sub)| Slot::Name { primary, sub });
wildcard.or(equals).or(name)
}
}
@@ -556,6 +552,7 @@ mod test {
"=dev-ml/stdio-0.17*t:=[ocamlopt?]",
">=dev-libs/libgee-0-8.5:0..8=",
"<dev-haskell/wai-3.3:=[]",
">=kde-frameworks/kcrash-2.16.0:6*",
];
for atom in atoms {