pep508: add and and or mutators to MarkerTree

While this could be done by callers since the representation
of `MarkerTree` is public, they are just annoying enough to do
that I think it makes sense to provide them on `MarkerTree`
itself.

These could also be improved in the future to do even more
flattening of conjunctions/disjunctions (or perhaps even
more robust simplification). But for now, some basic flattening
is good enough.

These routines will be used to combine marker expressions when
merging forked resolutions.
This commit is contained in:
Andrew Gallant 2024-05-23 13:25:42 -04:00 committed by Andrew Gallant
parent 144566907e
commit a74c2c6792

View file

@ -1801,6 +1801,42 @@ impl MarkerTree {
}
}
}
/// Combine this marker tree with the one given via a conjunction.
///
/// This does some shallow flattening. That is, if `self` is a conjunction
/// already, then `tree` is added to it instead of creating a new
/// conjunction.
pub fn and(&mut self, tree: MarkerTree) {
match *self {
MarkerTree::Expression(_) | MarkerTree::Or(_) => {
let this = std::mem::replace(self, MarkerTree::And(vec![]));
*self = MarkerTree::And(vec![this]);
}
_ => {}
}
if let MarkerTree::And(ref mut exprs) = *self {
exprs.push(tree);
}
}
/// Combine this marker tree with the one given via a disjunction.
///
/// This does some shallow flattening. That is, if `self` is a disjunction
/// already, then `tree` is added to it instead of creating a new
/// disjunction.
pub fn or(&mut self, tree: MarkerTree) {
match *self {
MarkerTree::Expression(_) | MarkerTree::And(_) => {
let this = std::mem::replace(self, MarkerTree::And(vec![]));
*self = MarkerTree::Or(vec![this]);
}
_ => {}
}
if let MarkerTree::Or(ref mut exprs) = *self {
exprs.push(tree);
}
}
}
impl Display for MarkerTree {