From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id E5B421FF0E0 for ; Thu, 09 Jul 2026 13:59:23 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 919322168E; Thu, 09 Jul 2026 13:58:03 +0200 (CEST) From: Lukas Wagner To: pbs-devel@lists.proxmox.com, pve-devel@lists.proxmox.com Subject: [PATCH proxmox 04/29] notify: matcher: break out severity matcher into submodule Date: Thu, 9 Jul 2026 13:56:51 +0200 Message-ID: <20260709115716.299836-5-l.wagner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260709115716.299836-1-l.wagner@proxmox.com> References: <20260709115716.299836-1-l.wagner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1783598237956 X-SPAM-LEVEL: Spam detection results: 0 DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 6VMDTHIZBBCGANMCZRI3HMKBRKBC6W64 X-Message-ID-Hash: 6VMDTHIZBBCGANMCZRI3HMKBRKBC6W64 X-MailFrom: l.wagner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: No functional changes. Signed-off-by: Lukas Wagner --- proxmox-notify/src/matcher/mod.rs | 56 +++------------------- proxmox-notify/src/matcher/severity.rs | 66 ++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 49 deletions(-) create mode 100644 proxmox-notify/src/matcher/severity.rs diff --git a/proxmox-notify/src/matcher/mod.rs b/proxmox-notify/src/matcher/mod.rs index 720be1c4..d27ce465 100644 --- a/proxmox-notify/src/matcher/mod.rs +++ b/proxmox-notify/src/matcher/mod.rs @@ -13,7 +13,11 @@ use proxmox_schema::{ApiStringFormat, Schema, StringSchema, Updater, api, const_ use proxmox_time::{DailyDuration, parse_daily_duration}; use crate::schema::ENTITY_NAME_SCHEMA; -use crate::{Error, Notification, Origin, Severity}; +use crate::{Error, Notification, Origin}; + +pub mod severity; + +use severity::SeverityMatcher; pub const MATCHER_TYPENAME: &str = "matcher"; @@ -337,46 +341,6 @@ impl MatcherConfig { } } -/// Match severity of the notification. -#[derive(Clone, Debug)] -pub struct SeverityMatcher { - severities: Vec, -} - -proxmox_serde::forward_deserialize_to_from_str!(SeverityMatcher); -proxmox_serde::forward_serialize_to_display!(SeverityMatcher); - -/// Common trait implemented by all matching directives -impl MatchDirective for SeverityMatcher { - /// Check if this directive matches a given notification - fn matches(&self, notification: &Notification) -> Result { - Ok(self.severities.contains(¬ification.metadata.severity)) - } -} - -impl fmt::Display for SeverityMatcher { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let severities: Vec = self.severities.iter().map(|s| format!("{s}")).collect(); - f.write_str(&severities.join(",")) - } -} - -impl FromStr for SeverityMatcher { - type Err = Error; - fn from_str(s: &str) -> Result { - let mut severities = Vec::new(); - - for element in s.split(',') { - let element = element.trim(); - let severity: Severity = element.parse()?; - - severities.push(severity) - } - - Ok(Self { severities }) - } -} - /// Match timestamp of the notification. #[derive(Clone, Debug)] pub struct CalendarMatcher { @@ -464,6 +428,8 @@ pub fn check_matches<'a>( #[cfg(test)] mod tests { + use crate::Severity; + use super::*; use serde_json::Value; use std::collections::HashMap; @@ -505,14 +471,6 @@ mod tests { assert!("regex:'3=b.*".parse::().is_err()); assert!("invalid:'bar=b.*".parse::().is_err()); } - #[test] - fn test_severities() { - let notification = - Notification::from_template(Severity::Notice, "test", Value::Null, Default::default()); - - let matcher: SeverityMatcher = "info,notice,warning,error".parse().unwrap(); - assert!(matcher.matches(¬ification).unwrap()); - } #[test] fn test_empty_matcher_matches_always() { diff --git a/proxmox-notify/src/matcher/severity.rs b/proxmox-notify/src/matcher/severity.rs new file mode 100644 index 00000000..4b126d85 --- /dev/null +++ b/proxmox-notify/src/matcher/severity.rs @@ -0,0 +1,66 @@ +use std::fmt; +use std::str::FromStr; + +use crate::{Error, Notification, Severity}; + +use super::MatchDirective; + +/// Match severity of the notification. +#[derive(Clone, Debug)] +pub struct SeverityMatcher { + severities: Vec, +} + +/// Common trait implemented by all matching directives +impl MatchDirective for SeverityMatcher { + /// Check if this directive matches a given notification + fn matches(&self, notification: &Notification) -> Result { + Ok(self.severities.contains(¬ification.metadata.severity)) + } +} + +impl fmt::Display for SeverityMatcher { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let severities: Vec = self.severities.iter().map(|s| format!("{s}")).collect(); + f.write_str(&severities.join(",")) + } +} + +impl FromStr for SeverityMatcher { + type Err = Error; + + fn from_str(s: &str) -> Result { + let mut severities = Vec::new(); + + for element in s.split(',') { + let element = element.trim(); + let severity: Severity = element.parse()?; + + severities.push(severity) + } + + Ok(Self { severities }) + } +} + +proxmox_serde::forward_deserialize_to_from_str!(SeverityMatcher); +proxmox_serde::forward_serialize_to_display!(SeverityMatcher); + +#[cfg(test)] +mod test { + use serde_json::Value; + + use crate::{ + Notification, Severity, + matcher::{MatchDirective as _, severity::SeverityMatcher}, + }; + + #[test] + fn test_severities() { + let notification = + Notification::from_template(Severity::Notice, "test", Value::Null, Default::default()); + + let matcher: SeverityMatcher = "info,notice,warning,error".parse().unwrap(); + assert!(matcher.matches(¬ification).unwrap()); + } +} -- 2.47.3