
- Add complete hymnal API with search, themes, and responsive readings - Implement hymn title lookup for bulletins (#319 → #319 - Hymn Title) - Add Bible book abbreviation support (Matt → Matthew, etc.) - Enhance scripture processing to handle verse ranges (Matt 1:21-23) - Add hymnal database schema with SDA 1985 and 1941 hymnals support - Implement advanced hymnal search with fuzzy matching and themes - Update bulletin processing to auto-populate hymn titles from database
856 lines
27 KiB
Rust
856 lines
27 KiB
Rust
use chrono::{DateTime, NaiveDate, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
use sqlx::FromRow;
|
|
use uuid::Uuid;
|
|
use crate::utils::datetime::DateTimeWithTimezone;
|
|
use crate::utils::sanitize::{SanitizeOutput, sanitize_string, sanitize_option_string};
|
|
|
|
pub mod media;
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct User {
|
|
pub id: Uuid,
|
|
pub username: String, // NOT NULL
|
|
pub email: Option<String>, // nullable
|
|
pub name: Option<String>, // nullable
|
|
pub avatar_url: Option<String>, // nullable
|
|
pub role: Option<String>, // nullable (has default)
|
|
pub verified: Option<bool>, // nullable (has default)
|
|
pub created_at: Option<DateTime<Utc>>, // nullable (has default)
|
|
pub updated_at: Option<DateTime<Utc>>, // nullable (has default)
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct Member {
|
|
pub id: Uuid,
|
|
pub first_name: String,
|
|
pub last_name: String,
|
|
pub email: Option<String>,
|
|
pub phone: Option<String>,
|
|
pub address: Option<String>,
|
|
pub date_of_birth: Option<NaiveDate>,
|
|
pub membership_status: Option<String>,
|
|
pub join_date: Option<NaiveDate>,
|
|
pub baptism_date: Option<NaiveDate>,
|
|
pub notes: Option<String>,
|
|
pub emergency_contact_name: Option<String>,
|
|
pub emergency_contact_phone: Option<String>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateMemberRequest {
|
|
pub first_name: String,
|
|
pub last_name: String,
|
|
pub email: Option<String>,
|
|
pub phone: Option<String>,
|
|
pub address: Option<String>,
|
|
pub date_of_birth: Option<NaiveDate>,
|
|
pub membership_status: Option<String>,
|
|
pub join_date: Option<NaiveDate>,
|
|
pub baptism_date: Option<NaiveDate>,
|
|
pub notes: Option<String>,
|
|
pub emergency_contact_name: Option<String>,
|
|
pub emergency_contact_phone: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct Bulletin {
|
|
pub id: Uuid,
|
|
pub title: String,
|
|
pub date: NaiveDate,
|
|
pub url: Option<String>,
|
|
pub pdf_url: Option<String>,
|
|
pub is_active: Option<bool>,
|
|
pub pdf_file: Option<String>,
|
|
pub sabbath_school: Option<String>,
|
|
pub divine_worship: Option<String>,
|
|
pub scripture_reading: Option<String>,
|
|
pub sunset: Option<String>,
|
|
pub cover_image: Option<String>,
|
|
pub pdf_path: Option<String>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct Event {
|
|
pub id: Uuid,
|
|
pub title: String,
|
|
pub description: String,
|
|
pub start_time: DateTime<Utc>,
|
|
pub end_time: DateTime<Utc>,
|
|
pub location: String,
|
|
pub location_url: Option<String>,
|
|
pub image: Option<String>,
|
|
pub thumbnail: Option<String>,
|
|
pub category: String,
|
|
pub is_featured: Option<bool>,
|
|
pub recurring_type: Option<String>,
|
|
pub approved_from: Option<String>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct PendingEvent {
|
|
pub id: Uuid,
|
|
pub title: String, // NOT NULL
|
|
pub description: String, // NOT NULL
|
|
pub start_time: DateTime<Utc>, // NOT NULL
|
|
pub end_time: DateTime<Utc>, // NOT NULL
|
|
pub location: String, // NOT NULL
|
|
pub location_url: Option<String>, // nullable
|
|
pub image: Option<String>, // nullable
|
|
pub thumbnail: Option<String>, // nullable
|
|
pub category: String, // NOT NULL
|
|
pub is_featured: Option<bool>, // nullable (has default)
|
|
pub recurring_type: Option<String>, // nullable
|
|
pub approval_status: Option<String>, // nullable (has default)
|
|
pub submitted_at: Option<DateTime<Utc>>, // nullable (has default)
|
|
pub bulletin_week: String, // NOT NULL
|
|
pub admin_notes: Option<String>, // nullable
|
|
pub submitter_email: Option<String>, // nullable
|
|
pub email_sent: Option<bool>, // nullable (has default)
|
|
pub pending_email_sent: Option<bool>, // nullable (has default)
|
|
pub rejection_email_sent: Option<bool>, // nullable (has default)
|
|
pub approval_email_sent: Option<bool>, // nullable (has default)
|
|
pub created_at: Option<DateTime<Utc>>, // nullable (has default)
|
|
pub updated_at: Option<DateTime<Utc>>, // nullable (has default)
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct ChurchConfig {
|
|
pub id: Uuid,
|
|
pub church_name: String,
|
|
pub contact_email: String,
|
|
pub contact_phone: Option<String>,
|
|
pub church_address: String,
|
|
pub po_box: Option<String>,
|
|
pub google_maps_url: Option<String>,
|
|
pub about_text: String,
|
|
pub api_keys: Option<serde_json::Value>,
|
|
pub jellyfin_server_url: Option<String>,
|
|
pub brand_color: String,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct ApiResponse<T> {
|
|
pub success: bool,
|
|
pub data: Option<T>,
|
|
pub message: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct LoginRequest {
|
|
pub username: String,
|
|
pub password: String,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct LoginResponse {
|
|
pub token: String,
|
|
pub user: User,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateBulletinRequest {
|
|
pub title: String,
|
|
pub date: NaiveDate,
|
|
pub url: Option<String>,
|
|
pub cover_image: Option<String>,
|
|
pub sabbath_school: Option<String>,
|
|
pub divine_worship: Option<String>,
|
|
pub scripture_reading: Option<String>,
|
|
pub sunset: Option<String>,
|
|
pub is_active: Option<bool>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize)]
|
|
pub struct CreateEventRequest {
|
|
pub title: String,
|
|
pub description: String,
|
|
pub start_time: DateTime<Utc>,
|
|
pub end_time: DateTime<Utc>,
|
|
pub location: String,
|
|
pub location_url: Option<String>,
|
|
pub category: String,
|
|
pub is_featured: Option<bool>,
|
|
pub recurring_type: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct SubmitEventRequest {
|
|
pub title: String,
|
|
pub description: String,
|
|
pub start_time: DateTime<Utc>,
|
|
pub end_time: DateTime<Utc>,
|
|
pub location: String,
|
|
pub location_url: Option<String>,
|
|
pub category: String,
|
|
pub is_featured: Option<bool>,
|
|
pub recurring_type: Option<String>,
|
|
pub bulletin_week: String,
|
|
pub submitter_email: Option<String>,
|
|
pub image: Option<String>,
|
|
pub thumbnail: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct PaginatedResponse<T> {
|
|
pub items: Vec<T>,
|
|
pub total: i64,
|
|
pub page: i32,
|
|
pub per_page: i32,
|
|
pub has_more: bool,
|
|
}
|
|
|
|
// Hymnal-specific paginated response with "results" field
|
|
#[derive(Debug, Serialize)]
|
|
pub struct HymnalPaginatedResponse<T> {
|
|
pub results: Vec<T>,
|
|
pub total: i64,
|
|
pub page: i32,
|
|
pub per_page: i32,
|
|
pub has_more: bool,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct PaginationParams {
|
|
pub page: Option<i64>,
|
|
pub per_page: Option<i64>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
pub struct BibleVerse {
|
|
pub id: Uuid,
|
|
pub reference: String,
|
|
pub text: String,
|
|
pub is_active: Option<bool>,
|
|
pub created_at: Option<chrono::DateTime<chrono::Utc>>,
|
|
pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Personnel {
|
|
pub ss_leader: String,
|
|
pub ss_teacher: String,
|
|
pub mission_story: String,
|
|
pub song_leader: String,
|
|
pub announcements: String,
|
|
pub offering: String,
|
|
pub special_music: String,
|
|
pub speaker: String,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct ScheduleData {
|
|
pub date: String,
|
|
pub personnel: Personnel,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct ConferenceData {
|
|
pub date: String,
|
|
pub offering_focus: String,
|
|
pub sunset_tonight: String,
|
|
pub sunset_next_friday: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct DateQuery {
|
|
pub date: Option<String>,
|
|
}
|
|
|
|
|
|
// Database model for schedule
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct Schedule {
|
|
pub id: Uuid,
|
|
pub date: NaiveDate,
|
|
pub song_leader: Option<String>,
|
|
pub ss_teacher: Option<String>,
|
|
pub ss_leader: Option<String>,
|
|
pub mission_story: Option<String>,
|
|
pub special_program: Option<String>,
|
|
pub sermon_speaker: Option<String>,
|
|
pub scripture: Option<String>,
|
|
pub offering: Option<String>,
|
|
pub deacons: Option<String>,
|
|
pub special_music: Option<String>,
|
|
pub childrens_story: Option<String>,
|
|
pub afternoon_program: Option<String>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
// Contact form models
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct ContactRequest {
|
|
pub first_name: String,
|
|
pub last_name: String,
|
|
pub email: String,
|
|
pub phone: Option<String>,
|
|
pub message: String,
|
|
pub subject: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Contact {
|
|
pub first_name: String,
|
|
pub last_name: String,
|
|
pub email: String,
|
|
pub phone: Option<String>,
|
|
pub message: String,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct ContactEmail {
|
|
pub first_name: String,
|
|
pub last_name: String,
|
|
pub email: String,
|
|
pub phone: Option<String>,
|
|
pub message: String,
|
|
pub subject: Option<String>,
|
|
}
|
|
|
|
// V2 Contact form models - simplified with just 'name'
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct ContactRequestV2 {
|
|
pub name: String,
|
|
pub email: String,
|
|
pub phone: Option<String>,
|
|
pub message: String,
|
|
pub subject: Option<String>,
|
|
}
|
|
|
|
// V2 API Models with enhanced timezone handling
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct EventV2 {
|
|
pub id: Uuid,
|
|
pub title: String,
|
|
pub description: String,
|
|
pub start_time: DateTimeWithTimezone,
|
|
pub end_time: DateTimeWithTimezone,
|
|
pub location: String,
|
|
pub location_url: Option<String>,
|
|
pub image: Option<String>,
|
|
pub thumbnail: Option<String>,
|
|
pub category: String,
|
|
pub is_featured: Option<bool>,
|
|
pub recurring_type: Option<String>,
|
|
pub timezone: String,
|
|
pub approved_from: Option<String>,
|
|
pub created_at: Option<DateTimeWithTimezone>,
|
|
pub updated_at: Option<DateTimeWithTimezone>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct PendingEventV2 {
|
|
pub id: Uuid,
|
|
pub title: String,
|
|
pub description: String,
|
|
pub start_time: DateTimeWithTimezone,
|
|
pub end_time: DateTimeWithTimezone,
|
|
pub location: String,
|
|
pub location_url: Option<String>,
|
|
pub image: Option<String>,
|
|
pub thumbnail: Option<String>,
|
|
pub category: String,
|
|
pub is_featured: Option<bool>,
|
|
pub recurring_type: Option<String>,
|
|
pub timezone: String,
|
|
pub approval_status: Option<String>,
|
|
pub submitted_at: Option<DateTimeWithTimezone>,
|
|
pub bulletin_week: String,
|
|
pub admin_notes: Option<String>,
|
|
pub submitter_email: Option<String>,
|
|
pub email_sent: Option<bool>,
|
|
pub pending_email_sent: Option<bool>,
|
|
pub rejection_email_sent: Option<bool>,
|
|
pub approval_email_sent: Option<bool>,
|
|
pub created_at: Option<DateTimeWithTimezone>,
|
|
pub updated_at: Option<DateTimeWithTimezone>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateEventRequestV2 {
|
|
pub title: String,
|
|
pub description: String,
|
|
pub start_time: String,
|
|
pub end_time: String,
|
|
pub location: String,
|
|
pub location_url: Option<String>,
|
|
pub category: String,
|
|
pub is_featured: Option<bool>,
|
|
pub recurring_type: Option<String>,
|
|
pub timezone: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct SubmitEventRequestV2 {
|
|
pub title: String,
|
|
pub description: String,
|
|
pub start_time: String,
|
|
pub end_time: String,
|
|
pub location: String,
|
|
pub location_url: Option<String>,
|
|
pub category: String,
|
|
pub is_featured: Option<bool>,
|
|
pub recurring_type: Option<String>,
|
|
pub bulletin_week: String,
|
|
pub submitter_email: Option<String>,
|
|
pub timezone: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct BulletinV2 {
|
|
pub id: Uuid,
|
|
pub title: String,
|
|
pub date: NaiveDate,
|
|
pub url: Option<String>,
|
|
pub cover_image: Option<String>,
|
|
pub cover_image_url: Option<String>,
|
|
pub pdf_url: Option<String>,
|
|
pub is_active: Option<bool>,
|
|
pub pdf_file: Option<String>,
|
|
pub sabbath_school: Option<String>,
|
|
pub divine_worship: Option<String>,
|
|
pub scripture_reading: Option<String>,
|
|
pub sunset: Option<String>,
|
|
pub pdf_path: Option<String>,
|
|
pub created_at: Option<DateTimeWithTimezone>,
|
|
pub updated_at: Option<DateTimeWithTimezone>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ScheduleV2 {
|
|
pub id: Uuid,
|
|
pub date: NaiveDate,
|
|
pub song_leader: Option<String>,
|
|
pub ss_teacher: Option<String>,
|
|
pub ss_leader: Option<String>,
|
|
pub mission_story: Option<String>,
|
|
pub special_program: Option<String>,
|
|
pub sermon_speaker: Option<String>,
|
|
pub scripture: Option<String>,
|
|
pub offering: Option<String>,
|
|
pub deacons: Option<String>,
|
|
pub special_music: Option<String>,
|
|
pub childrens_story: Option<String>,
|
|
pub afternoon_program: Option<String>,
|
|
pub created_at: Option<DateTimeWithTimezone>,
|
|
pub updated_at: Option<DateTimeWithTimezone>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct BibleVerseV2 {
|
|
pub id: Uuid,
|
|
pub reference: String,
|
|
pub text: String,
|
|
pub is_active: Option<bool>,
|
|
pub created_at: Option<DateTimeWithTimezone>,
|
|
pub updated_at: Option<DateTimeWithTimezone>,
|
|
}
|
|
|
|
// Hymnal Models
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct Hymnal {
|
|
pub id: Uuid,
|
|
pub name: String,
|
|
pub code: String,
|
|
pub description: Option<String>,
|
|
pub year: Option<i32>,
|
|
pub language: Option<String>,
|
|
pub is_active: Option<bool>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct Hymn {
|
|
pub id: Uuid,
|
|
pub hymnal_id: Uuid,
|
|
pub number: i32,
|
|
pub title: String,
|
|
pub content: String,
|
|
pub is_favorite: Option<bool>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct HymnWithHymnal {
|
|
pub id: Uuid,
|
|
pub hymnal_id: Uuid,
|
|
pub hymnal_name: String,
|
|
pub hymnal_code: String,
|
|
pub hymnal_year: Option<i32>,
|
|
pub number: i32,
|
|
pub title: String,
|
|
pub content: String,
|
|
pub is_favorite: Option<bool>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct ThematicList {
|
|
pub id: Uuid,
|
|
pub hymnal_id: Uuid,
|
|
pub name: String,
|
|
pub sort_order: Option<i32>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct ThematicAmbit {
|
|
pub id: Uuid,
|
|
pub thematic_list_id: Uuid,
|
|
pub name: String,
|
|
pub start_number: i32,
|
|
pub end_number: i32,
|
|
pub sort_order: Option<i32>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ThematicListWithAmbits {
|
|
pub id: Uuid,
|
|
pub hymnal_id: Uuid,
|
|
pub name: String,
|
|
pub sort_order: Option<i32>,
|
|
pub ambits: Vec<ThematicAmbit>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
|
pub struct ResponsiveReading {
|
|
pub id: Uuid,
|
|
pub number: i32,
|
|
pub title: String,
|
|
pub content: String,
|
|
pub is_favorite: Option<bool>,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub updated_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
// Hymnal search result structure
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct SearchResult {
|
|
pub hymn: HymnWithHymnal,
|
|
pub score: f64,
|
|
pub match_type: String,
|
|
}
|
|
|
|
// Hymnal request/query types
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct HymnSearchQuery {
|
|
pub q: Option<String>,
|
|
pub hymnal: Option<String>,
|
|
pub number: Option<i32>,
|
|
pub theme: Option<Uuid>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct ResponsiveReadingQuery {
|
|
pub q: Option<String>,
|
|
pub number: Option<i32>,
|
|
}
|
|
|
|
// SanitizeOutput trait implementations
|
|
impl SanitizeOutput for Bulletin {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.sabbath_school = sanitize_option_string(self.sabbath_school);
|
|
self.divine_worship = sanitize_option_string(self.divine_worship);
|
|
self.scripture_reading = sanitize_option_string(self.scripture_reading);
|
|
self.sunset = sanitize_option_string(self.sunset);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for BulletinV2 {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.sabbath_school = sanitize_option_string(self.sabbath_school);
|
|
self.divine_worship = sanitize_option_string(self.divine_worship);
|
|
self.scripture_reading = sanitize_option_string(self.scripture_reading);
|
|
self.sunset = sanitize_option_string(self.sunset);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for Event {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.description = sanitize_string(self.description);
|
|
self.location = sanitize_string(self.location);
|
|
self.category = sanitize_string(self.category);
|
|
self.location_url = sanitize_option_string(self.location_url);
|
|
self.approved_from = sanitize_option_string(self.approved_from);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for EventV2 {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.description = sanitize_string(self.description);
|
|
self.location = sanitize_string(self.location);
|
|
self.category = sanitize_string(self.category);
|
|
self.location_url = sanitize_option_string(self.location_url);
|
|
self.approved_from = sanitize_option_string(self.approved_from);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for PendingEvent {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.description = sanitize_string(self.description);
|
|
self.location = sanitize_string(self.location);
|
|
self.category = sanitize_string(self.category);
|
|
self.location_url = sanitize_option_string(self.location_url);
|
|
self.admin_notes = sanitize_option_string(self.admin_notes);
|
|
self.submitter_email = sanitize_option_string(self.submitter_email);
|
|
self.bulletin_week = sanitize_string(self.bulletin_week);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for PendingEventV2 {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.description = sanitize_string(self.description);
|
|
self.location = sanitize_string(self.location);
|
|
self.category = sanitize_string(self.category);
|
|
self.location_url = sanitize_option_string(self.location_url);
|
|
self.admin_notes = sanitize_option_string(self.admin_notes);
|
|
self.submitter_email = sanitize_option_string(self.submitter_email);
|
|
self.bulletin_week = sanitize_string(self.bulletin_week);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for BibleVerse {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.reference = sanitize_string(self.reference);
|
|
self.text = sanitize_string(self.text);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for BibleVerseV2 {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.reference = sanitize_string(self.reference);
|
|
self.text = sanitize_string(self.text);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for Member {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.first_name = sanitize_string(self.first_name);
|
|
self.last_name = sanitize_string(self.last_name);
|
|
self.address = sanitize_option_string(self.address);
|
|
self.notes = sanitize_option_string(self.notes);
|
|
self.emergency_contact_name = sanitize_option_string(self.emergency_contact_name);
|
|
self.membership_status = sanitize_option_string(self.membership_status);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for Schedule {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.song_leader = sanitize_option_string(self.song_leader);
|
|
self.ss_teacher = sanitize_option_string(self.ss_teacher);
|
|
self.ss_leader = sanitize_option_string(self.ss_leader);
|
|
self.mission_story = sanitize_option_string(self.mission_story);
|
|
self.special_program = sanitize_option_string(self.special_program);
|
|
self.sermon_speaker = sanitize_option_string(self.sermon_speaker);
|
|
self.scripture = sanitize_option_string(self.scripture);
|
|
self.offering = sanitize_option_string(self.offering);
|
|
self.deacons = sanitize_option_string(self.deacons);
|
|
self.special_music = sanitize_option_string(self.special_music);
|
|
self.childrens_story = sanitize_option_string(self.childrens_story);
|
|
self.afternoon_program = sanitize_option_string(self.afternoon_program);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ScheduleV2 {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.song_leader = sanitize_option_string(self.song_leader);
|
|
self.ss_teacher = sanitize_option_string(self.ss_teacher);
|
|
self.ss_leader = sanitize_option_string(self.ss_leader);
|
|
self.mission_story = sanitize_option_string(self.mission_story);
|
|
self.special_program = sanitize_option_string(self.special_program);
|
|
self.sermon_speaker = sanitize_option_string(self.sermon_speaker);
|
|
self.scripture = sanitize_option_string(self.scripture);
|
|
self.offering = sanitize_option_string(self.offering);
|
|
self.deacons = sanitize_option_string(self.deacons);
|
|
self.special_music = sanitize_option_string(self.special_music);
|
|
self.childrens_story = sanitize_option_string(self.childrens_story);
|
|
self.afternoon_program = sanitize_option_string(self.afternoon_program);
|
|
self
|
|
}
|
|
}
|
|
|
|
// Implement for collections
|
|
impl<T: SanitizeOutput> SanitizeOutput for Vec<T> {
|
|
fn sanitize_output(self) -> Self {
|
|
self.into_iter().map(|item| item.sanitize_output()).collect()
|
|
}
|
|
}
|
|
|
|
impl<T: SanitizeOutput> SanitizeOutput for Option<T> {
|
|
fn sanitize_output(self) -> Self {
|
|
self.map(|item| item.sanitize_output())
|
|
}
|
|
}
|
|
|
|
impl<T: SanitizeOutput> SanitizeOutput for PaginatedResponse<T> {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.items = self.items.sanitize_output();
|
|
self
|
|
}
|
|
}
|
|
|
|
impl<T: SanitizeOutput> SanitizeOutput for HymnalPaginatedResponse<T> {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.results = self.results.sanitize_output();
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for Personnel {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.ss_leader = sanitize_string(self.ss_leader);
|
|
self.ss_teacher = sanitize_string(self.ss_teacher);
|
|
self.mission_story = sanitize_string(self.mission_story);
|
|
self.song_leader = sanitize_string(self.song_leader);
|
|
self.announcements = sanitize_string(self.announcements);
|
|
self.offering = sanitize_string(self.offering);
|
|
self.special_music = sanitize_string(self.special_music);
|
|
self.speaker = sanitize_string(self.speaker);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ScheduleData {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.date = sanitize_string(self.date);
|
|
self.personnel = self.personnel.sanitize_output();
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ConferenceData {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.date = sanitize_string(self.date);
|
|
self.offering_focus = sanitize_string(self.offering_focus);
|
|
self.sunset_tonight = sanitize_string(self.sunset_tonight);
|
|
self.sunset_next_friday = sanitize_string(self.sunset_next_friday);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ChurchConfig {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.church_name = sanitize_string(self.church_name);
|
|
self.contact_email = sanitize_string(self.contact_email);
|
|
self.contact_phone = sanitize_option_string(self.contact_phone);
|
|
self.church_address = sanitize_string(self.church_address);
|
|
self.po_box = sanitize_option_string(self.po_box);
|
|
self.google_maps_url = sanitize_option_string(self.google_maps_url);
|
|
self.about_text = sanitize_string(self.about_text);
|
|
self.jellyfin_server_url = sanitize_option_string(self.jellyfin_server_url);
|
|
self.api_keys = self.api_keys.sanitize_output();
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for User {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.username = sanitize_string(self.username);
|
|
self.email = sanitize_option_string(self.email);
|
|
self.name = sanitize_option_string(self.name);
|
|
self.avatar_url = sanitize_option_string(self.avatar_url);
|
|
self.role = sanitize_option_string(self.role);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for Hymnal {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.name = sanitize_string(self.name);
|
|
self.code = sanitize_string(self.code);
|
|
self.description = sanitize_option_string(self.description);
|
|
self.language = sanitize_option_string(self.language);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for Hymn {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.content = sanitize_string(self.content);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for HymnWithHymnal {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.hymnal_name = sanitize_string(self.hymnal_name);
|
|
self.hymnal_code = sanitize_string(self.hymnal_code);
|
|
self.title = sanitize_string(self.title);
|
|
self.content = sanitize_string(self.content);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ThematicList {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.name = sanitize_string(self.name);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ThematicAmbit {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.name = sanitize_string(self.name);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ThematicListWithAmbits {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.name = sanitize_string(self.name);
|
|
self.ambits = self.ambits.sanitize_output();
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for ResponsiveReading {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.title = sanitize_string(self.title);
|
|
self.content = sanitize_string(self.content);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl SanitizeOutput for SearchResult {
|
|
fn sanitize_output(mut self) -> Self {
|
|
self.hymn = self.hymn.sanitize_output();
|
|
self.match_type = sanitize_string(self.match_type);
|
|
self
|
|
}
|
|
}
|