summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2024-11-29 12:36:59 +0100
committerSanto Cariotti <santo@dcariotti.me>2024-11-29 12:36:59 +0100
commit26d8aed5540677d539957dea16f95491499eff58 (patch)
treefc5f2ef0a5dd063e7a4a4fb4f63cfaed45d7e1ec
parent235a650d34348e8a7febea525b452b2b062cd1d5 (diff)
Use Expo on the AppState
This because since Rust 1.83 it is suggested to not use the static reference cloning
-rw-r--r--src/errors.rs7
-rw-r--r--src/expo.rs38
-rw-r--r--src/graphql/types/alert.rs1
-rw-r--r--src/main.rs2
-rw-r--r--src/state.rs4
5 files changed, 34 insertions, 18 deletions
diff --git a/src/errors.rs b/src/errors.rs
index 3dda65c..5f2a8dd 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -96,3 +96,10 @@ impl From<async_graphql::Error> for AppError {
AppError::BadRequest(value.message)
}
}
+
+/// A expo_push_notification_client::ValidationError is mapped to an `AppError::BadRequest`
+impl From<expo_push_notification_client::ValidationError> for AppError {
+ fn from(value: expo_push_notification_client::ValidationError) -> Self {
+ AppError::BadRequest(value.to_string())
+ }
+}
diff --git a/src/expo.rs b/src/expo.rs
index 1a6a4e5..f4cecc6 100644
--- a/src/expo.rs
+++ b/src/expo.rs
@@ -1,31 +1,35 @@
-use expo_push_notification_client::{Expo, ExpoClientOptions, ExpoPushMessage, ValidationError};
+use expo_push_notification_client::{Expo, ExpoClientOptions, ExpoPushMessage};
-/// Connection to an Expo client
-static mut EXPO_CONNECTION: Option<Expo> = None;
+use crate::errors::AppError;
/// Setup a new Expo API
-pub fn setup(access_token: String) {
- unsafe {
- EXPO_CONNECTION = Some(Expo::new(ExpoClientOptions {
- access_token: Some(access_token),
- }))
- }
+pub fn setup(access_token: String) -> Expo {
+ Expo::new(ExpoClientOptions {
+ access_token: Some(access_token),
+ })
}
/// Send notifications using Expo
-pub async fn send(tokens: Vec<String>, body: String, title: String) -> Result<(), ValidationError> {
- let expo = unsafe {
- EXPO_CONNECTION
- .clone()
- .expect("You need to call `setup()` first")
- };
-
+pub async fn send(
+ expo: Expo,
+ tokens: Vec<String>,
+ body: String,
+ title: String,
+) -> Result<(), AppError> {
let expo_push_message = ExpoPushMessage::builder(tokens)
.body(body)
.title(title)
.build()?;
- let _ = expo.send_push_notifications(expo_push_message).await;
+ if expo
+ .send_push_notifications(expo_push_message)
+ .await
+ .is_err()
+ {
+ return Err(AppError::BadRequest(
+ "Expo Notifications sending".to_string(),
+ ));
+ }
Ok(())
}
diff --git a/src/graphql/types/alert.rs b/src/graphql/types/alert.rs
index 007f471..cce2bee 100644
--- a/src/graphql/types/alert.rs
+++ b/src/graphql/types/alert.rs
@@ -305,6 +305,7 @@ pub mod mutations {
.collect();
expo::send(
+ (*state.expo).clone(),
tokens,
"New Alert!".to_string(),
match level.text {
diff --git a/src/main.rs b/src/main.rs
index 96cdc61..b9b7f87 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -31,11 +31,11 @@ use tracing::Span;
/// Create the app: setup everything and returns a `Router`
async fn create_app() -> Result<Router, AppError> {
logger::setup();
- expo::setup(CONFIG.expo_access_token.clone());
let dbclient = db::setup().await?;
let state = state::AppState {
client: Arc::new(dbclient),
+ expo: Arc::new(expo::setup(CONFIG.expo_access_token.clone())),
};
let schema = Schema::build(
diff --git a/src/state.rs b/src/state.rs
index 700f6ab..546a609 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1,5 +1,6 @@
use std::sync::Arc;
+use expo_push_notification_client::Expo;
use tokio_postgres::Client;
#[derive(Clone)]
@@ -7,4 +8,7 @@ use tokio_postgres::Client;
pub struct AppState {
/// PostgreSQL client synced via Arc
pub client: Arc<Client>,
+
+ /// Expo connection
+ pub expo: Arc<Expo>,
}