From 669e6b6e0d7a0a5fa71f4cec564cf37273ab7906 Mon Sep 17 00:00:00 2001
From: Eduardo Trujillo <ed@chromabits.com>
Date: Sat, 29 Oct 2022 13:24:35 -0700
Subject: [PATCH] feat(condition): Add Not condition

---
 Cargo.lock       | 12 ++++++++++++
 Cargo.toml       |  1 +
 src/condition.rs | 10 ++++++++++
 3 files changed, 23 insertions(+)

diff --git a/Cargo.lock b/Cargo.lock
index 0c80836..eeab304 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,6 +17,17 @@ version = "1.0.56"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27"
 
+[[package]]
+name = "async-recursion"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "async-trait"
 version = "0.1.52"
@@ -381,6 +392,7 @@ name = "nm-reactor"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "async-recursion",
  "async-trait",
  "clap",
  "collective",
diff --git a/Cargo.toml b/Cargo.toml
index 4c0a547..f3254c8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,3 +28,4 @@ num-traits = "0.2"
 futures = "0.3.18"
 async-trait = "0.1.52"
 nm-reactor_dbus_codegen = {path = "dbus_codegen"}
+async-recursion = "1.0"
diff --git a/src/condition.rs b/src/condition.rs
index a523683..7d03aa7 100644
--- a/src/condition.rs
+++ b/src/condition.rs
@@ -1,6 +1,7 @@
 use std::{collections::HashSet, sync::Arc};
 
 use anyhow::Result;
+use async_recursion::async_recursion;
 use dbus::nonblock::SyncConnection;
 use futures::{stream, StreamExt};
 use serde_derive::{Deserialize, Serialize};
@@ -62,9 +63,13 @@ pub enum Condition {
     StateIsAnyOf {
         states: HashSet<State>,
     },
+    Not {
+        condition: Box<Condition>,
+    }
 }
 
 impl Condition {
+    #[async_recursion]
     pub async fn evaluate(&self, conn: &Arc<SyncConnection>) -> Result<bool> {
         match self {
             Condition::AlwaysTrue => Ok(true),
@@ -156,6 +161,11 @@ impl Condition {
 
                 Ok(states.contains(&manager.get_state().await?))
             }
+            Condition::Not { condition } => {
+                let result = condition.evaluate(conn).await?;
+
+                Ok(!result)
+            }
         }
     }
 }
-- 
GitLab