mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Annotates all API handlers and model structs with Utoipa macros to generate an OpenAPI 3.0 spec at runtime. Serves an interactive Swagger UI at /api/docs and the raw JSON spec at /api/docs/openapi.json, both publicly accessible outside the auth middleware. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
111 lines
3.0 KiB
Rust
111 lines
3.0 KiB
Rust
use crate::utils::date_serializer;
|
|
use chrono::{DateTime, Utc};
|
|
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::{error::Error, fmt, str::FromStr};
|
|
use utoipa::ToSchema;
|
|
|
|
#[derive(Clone, Serialize, Deserialize, ToSchema)]
|
|
pub struct Notification {
|
|
pub id: i64,
|
|
#[serde(with = "date_serializer")]
|
|
#[schema(value_type = String, format = DateTime)]
|
|
pub created_on: DateTime<Utc>,
|
|
pub notification_type: NotificationType,
|
|
pub title: String,
|
|
pub body: String,
|
|
pub is_new: bool,
|
|
}
|
|
|
|
impl Notification {
|
|
pub fn new(
|
|
created_on: DateTime<Utc>,
|
|
notification_type: NotificationType,
|
|
title: String,
|
|
body: String,
|
|
is_new: bool,
|
|
) -> Self {
|
|
Self {
|
|
id: -1,
|
|
created_on: created_on,
|
|
notification_type: notification_type,
|
|
title: title,
|
|
body: body,
|
|
is_new: is_new,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Notification {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(
|
|
f,
|
|
"id={}, created_on={}, notification_type={}, is_new={}\ntitle={}\nbody={}",
|
|
self.id, self.created_on, self.notification_type, self.is_new, self.title, self.body
|
|
)
|
|
}
|
|
}
|
|
|
|
impl PartialEq for Notification {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.id == other.id
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
|
|
pub enum NotificationType {
|
|
NewDeviceFound,
|
|
DeviceOnlineAfterTime,
|
|
DeviceChanged,
|
|
Other,
|
|
}
|
|
|
|
impl fmt::Display for NotificationType {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
Self::NewDeviceFound => write!(f, "NewDeviceFound"),
|
|
Self::DeviceOnlineAfterTime => write!(f, "DeviceOnlineAfterTime"),
|
|
Self::DeviceChanged => write!(f, "DeviceChanged"),
|
|
Self::Other => write!(f, "Other"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct NotificationTypeParseError;
|
|
|
|
impl fmt::Display for NotificationTypeParseError {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
write!(f, "Error parsing notification type")
|
|
}
|
|
}
|
|
|
|
impl Error for NotificationTypeParseError {}
|
|
|
|
impl FromStr for NotificationType {
|
|
type Err = NotificationTypeParseError;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s {
|
|
"NewDeviceFound" => Ok(NotificationType::NewDeviceFound),
|
|
"DeviceOnlineAfterTime" => Ok(NotificationType::DeviceOnlineAfterTime),
|
|
_ => Ok(NotificationType::Other),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ToSql for NotificationType {
|
|
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
|
|
Ok(self.to_string().into())
|
|
}
|
|
}
|
|
|
|
impl FromSql for NotificationType {
|
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
|
value
|
|
.as_str()?
|
|
.parse()
|
|
.map_err(|e| FromSqlError::Other(Box::new(e)))
|
|
}
|
|
}
|