remindrs/src/api.rs
finga 7ad6f610d1 Use once_cell to keep the configuration
In order to keep the configuration globally available use
`once_cell`. Also check for a valid email address in the part which is
receiving the data from the api.
2023-02-06 10:00:45 +01:00

71 lines
1.7 KiB
Rust

use crate::{schema, AppState, NewReminder};
use anyhow::Error;
use axum::{
extract::State,
http::StatusCode,
response::{IntoResponse, Response, Result},
Json,
};
use diesel::prelude::*;
use lettre::message::Mailbox;
use serde::Deserialize;
use time::OffsetDateTime;
use tracing::{error, trace};
pub struct ServerError(Error);
impl IntoResponse for ServerError {
fn into_response(self) -> Response {
error!("{}", self.0);
(StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong.").into_response()
}
}
impl<E> From<E> for ServerError
where
E: Into<Error>,
{
fn from(err: E) -> Self {
Self(err.into())
}
}
#[derive(Debug, Deserialize)]
pub struct Reminder {
#[serde(with = "time::serde::iso8601")]
planned: OffsetDateTime,
title: String,
message: String,
receiver: Mailbox,
}
#[allow(clippy::unused_async)]
pub async fn create_reminder(
State(state): State<AppState>,
Json(data): Json<Reminder>,
) -> Result<impl IntoResponse, ServerError> {
let reminder = NewReminder {
created: OffsetDateTime::now_utc(),
planned: data.planned,
title: &data.title,
message: &data.message,
receiver: &data.receiver.to_string(),
};
trace!(?data, "received data");
diesel::insert_into(schema::reminders::table)
.values(&reminder)
.execute(&mut state.db_pool.get()?)?;
trace!("unpark reminder thread to reschedule next run");
state.reminder.thread().unpark();
Ok((StatusCode::CREATED, "Reminder created".to_string()))
}
#[allow(clippy::unused_async)]
pub async fn not_found() -> impl IntoResponse {
(StatusCode::NOT_FOUND, "Page not found")
}