use std::hash::{Hash, Hasher};
use indexmap::Equivalent;
use salvo::prelude::*;
use serde::{Deserialize, Serialize};
use crate::push::condition;
use crate::push::{Action, FlattenedJson, MissingPatternError, PushConditionRoomCtx, PushRule};
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct PatternedPushRule {
pub actions: Vec<Action>,
pub default: bool,
pub enabled: bool,
pub rule_id: String,
pub pattern: String,
}
impl PatternedPushRule {
pub fn applies_to(&self, key: &str, event: &FlattenedJson, context: &PushConditionRoomCtx) -> bool {
if event.contains_mentions() {
return false;
}
if event.get_str("sender").is_some_and(|sender| sender == context.user_id) {
return false;
}
self.enabled && condition::check_event_match(event, key, &self.pattern, context)
}
}
#[derive(Debug)]
#[allow(clippy::exhaustive_structs)]
pub struct PatternedPushRuleInit {
pub actions: Vec<Action>,
pub default: bool,
pub enabled: bool,
pub rule_id: String,
pub pattern: String,
}
impl From<PatternedPushRuleInit> for PatternedPushRule {
fn from(init: PatternedPushRuleInit) -> Self {
let PatternedPushRuleInit {
actions,
default,
enabled,
rule_id,
pattern,
} = init;
Self {
actions,
default,
enabled,
rule_id,
pattern,
}
}
}
impl Hash for PatternedPushRule {
fn hash<H: Hasher>(&self, state: &mut H) {
self.rule_id.hash(state);
}
}
impl PartialEq for PatternedPushRule {
fn eq(&self, other: &Self) -> bool {
self.rule_id == other.rule_id
}
}
impl Eq for PatternedPushRule {}
impl Equivalent<PatternedPushRule> for str {
fn equivalent(&self, key: &PatternedPushRule) -> bool {
self == key.rule_id
}
}
#[derive(ToSchema, Deserialize, Serialize, Clone, Debug)]
pub struct NewPatternedPushRule {
pub rule_id: String,
pub pattern: String,
pub actions: Vec<Action>,
}
impl NewPatternedPushRule {
pub fn new(rule_id: String, pattern: String, actions: Vec<Action>) -> Self {
Self {
rule_id,
pattern,
actions,
}
}
}
impl From<NewPatternedPushRule> for PatternedPushRule {
fn from(new_rule: NewPatternedPushRule) -> Self {
let NewPatternedPushRule {
rule_id,
pattern,
actions,
} = new_rule;
Self {
actions,
default: false,
enabled: true,
rule_id,
pattern,
}
}
}
impl From<PatternedPushRule> for PushRule {
fn from(push_rule: PatternedPushRule) -> Self {
let PatternedPushRule {
actions,
default,
enabled,
rule_id,
pattern,
..
} = push_rule;
Self {
actions,
default,
enabled,
rule_id,
conditions: None,
pattern: Some(pattern),
}
}
}
impl From<PatternedPushRuleInit> for PushRule {
fn from(init: PatternedPushRuleInit) -> Self {
let PatternedPushRuleInit {
actions,
default,
enabled,
rule_id,
pattern,
} = init;
Self {
actions,
default,
enabled,
rule_id,
pattern: Some(pattern),
conditions: None,
}
}
}
impl TryFrom<PushRule> for PatternedPushRule {
type Error = MissingPatternError;
fn try_from(push_rule: PushRule) -> Result<Self, Self::Error> {
if let PushRule {
actions,
default,
enabled,
rule_id,
pattern: Some(pattern),
..
} = push_rule
{
Ok(PatternedPushRuleInit {
actions,
default,
enabled,
rule_id,
pattern,
}
.into())
} else {
Err(MissingPatternError)
}
}
}