/* * Copyright (C) 2025 Jonni Liljamo * * This file is licensed under AGPL-3.0-or-later, see NOTICE and LICENSE for * more information. */ use std::{collections::HashMap, sync::Arc}; use crate::{ config::{Config, NotifierConfig}, routes::message::MessageForm, service::{self, Service}, }; static USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); #[derive(Clone)] pub struct State { _client: reqwest::Client, pub services: Arc>>, pub notifiers: HashMap, } impl State { pub fn from_config(config: &Config) -> Result> { let client: reqwest::Client = reqwest::ClientBuilder::new() .user_agent(USER_AGENT) .build()?; let mut services: HashMap> = HashMap::new(); for (id, service_config) in &config.services { let service: Box = service::build(client.clone(), &*(*service_config))?; services.insert(id.clone(), service); } Ok(Self { _client: client, services: Arc::new(services), notifiers: config.notifiers.clone(), }) } pub fn find_notifier(&self, token: &str) -> Option<(&String, &NotifierConfig)> { self.notifiers.iter().find(|(_k, v)| v.token == token) } pub async fn send_message( &self, notifier: (&String, &NotifierConfig), form: &MessageForm, ) -> Result<(), Vec>> { let mut errs = vec![]; for (_k, v) in self .services .iter() .filter(|(k, _v)| notifier.1.services.contains(k)) { if let Err(err) = v.send(form).await { errs.push(err); }; } if !errs.is_empty() { Err(errs) } else { Ok(()) } } }