replace IfNot with Not, And, Or and Xor

This commit is contained in:
figsoda 2020-10-31 13:33:51 -04:00
parent 15d1ec67a8
commit 45d8523b3d
2 changed files with 34 additions and 47 deletions

View file

@ -65,6 +65,10 @@ pub enum Condition {
TitleExist,
ArtistExist,
AlbumExist,
Not(Box<Condition>),
And(Box<Condition>, Box<Condition>),
Or(Box<Condition>, Box<Condition>),
Xor(Box<Condition>, Box<Condition>),
}
impl<'de> Deserialize<'de> for Texts {
@ -110,7 +114,6 @@ impl<'de> Deserialize<'de> for Texts {
QueueAlbum,
Parts,
If,
IfNot,
}
struct IfVisitor;
@ -137,30 +140,6 @@ impl<'de> Deserialize<'de> for Texts {
}
}
struct IfNotVisitor;
impl<'de> Visitor<'de> for IfNotVisitor {
type Value = Texts;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("IfNot variant")
}
fn visit_seq<A: SeqAccess<'de>>(
self,
mut sa: A,
) -> Result<Self::Value, A::Error> {
let cond = sa
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
let no = sa.next_element()?.map_or_else(
|| Err(de::Error::invalid_length(1, &self)),
|x| Ok(Box::new(x)),
)?;
let yes = Box::new(sa.next_element()?.unwrap_or(Texts::Empty));
Ok(Texts::If(cond, yes, no))
}
}
let (variant, va) = ea.variant()?;
macro_rules! unit_variant {
@ -185,7 +164,6 @@ impl<'de> Deserialize<'de> for Texts {
Variant::QueueAlbum => unit_variant!(QueueAlbum),
Variant::Parts => Ok(Texts::Parts(va.newtype_variant()?)),
Variant::If => va.tuple_variant(3, IfVisitor),
Variant::IfNot => va.tuple_variant(3, IfNotVisitor),
}
}
}
@ -207,7 +185,6 @@ impl<'de> Deserialize<'de> for Texts {
"QueueAlbum",
"Parts",
"If",
"IfNot",
],
TextsVisitor,
)

View file

@ -244,26 +244,7 @@ fn flatten(
}
}
Texts::If(cond, box yes, box no) => {
let xs = if match cond {
Condition::Playing => current_track.is_some(),
Condition::Repeat => status.repeat,
Condition::Random => status.random,
Condition::Single => status.single == Some(true),
Condition::Oneshot => status.single == None,
Condition::Consume => status.consume,
Condition::TitleExist => {
matches!(current_track, Some(Track { title: Some(_), .. }))
}
Condition::ArtistExist => matches!(
current_track,
Some(Track {
artist: Some(_), ..
}),
),
Condition::AlbumExist => {
matches!(current_track, Some(Track { album: Some(_), .. }))
}
} {
let xs = if eval_cond(cond, status, current_track) {
yes
} else {
no
@ -272,3 +253,32 @@ fn flatten(
}
}
}
fn eval_cond(cond: &Condition, status: &Status, current_track: Option<&Track>) -> bool {
match cond {
Condition::Playing => current_track.is_some(),
Condition::Repeat => status.repeat,
Condition::Random => status.random,
Condition::Single => status.single == Some(true),
Condition::Oneshot => status.single == None,
Condition::Consume => status.consume,
Condition::TitleExist => matches!(current_track, Some(Track { title: Some(_), .. })),
Condition::ArtistExist => matches!(
current_track,
Some(Track {
artist: Some(_), ..
}),
),
Condition::AlbumExist => matches!(current_track, Some(Track { album: Some(_), .. })),
Condition::Not(box x) => !eval_cond(x, status, current_track),
Condition::And(box x, box y) => {
eval_cond(x, status, current_track) && eval_cond(y, status, current_track)
}
Condition::Or(box x, box y) => {
eval_cond(x, status, current_track) || eval_cond(y, status, current_track)
}
Condition::Xor(box x, box y) => {
eval_cond(x, status, current_track) ^ eval_cond(y, status, current_track)
}
}
}