//! Category objects (SPEC §14.3.3, §14.3.4 E-23, E-24). use serde::{Deserialize, Serialize}; use utoipa::ToSchema; use uuid::Uuid; use super::{ServerVersionSchema, TimestampSchema, UuidSchema}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "snake_case")] pub enum DefaultCategoryKey { Groceries, Restaurants, Home, Utilities, Transport, Travel, Entertainment, Health, Shopping, Other, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] pub struct Category { #[schema(value_type = UuidSchema)] pub id: Uuid, #[schema(required = true)] pub default_key: Option, #[schema(required = true)] pub name: Option, /// An icon token of SPEC §9.7. pub icon: String, /// A colour token of SPEC §9.7. pub color: String, #[schema(schema_with = super::int)] pub sort_order: i64, #[schema(value_type = TimestampSchema)] pub created_at: String, #[schema(value_type = TimestampSchema)] pub updated_at: String, #[schema(value_type = Option, required = true)] pub archived_at: Option, #[schema(value_type = Option, required = true)] pub deleted_at: Option, #[schema(value_type = ServerVersionSchema)] pub server_version: i64, } /// E-23 `POST /categories`. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] pub struct CreateCategoryRequest { pub name: String, pub icon: String, pub color: String, } /// E-24 `PATCH /categories/{category_id}`. `name`: absent = unchanged (`None`), `null` = reset a default category's /// name (`Some(None)`). #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] #[schema(min_properties = 1)] pub struct PatchCategoryRequest { #[serde( default, deserialize_with = "super::double_option", skip_serializing_if = "Option::is_none" )] #[schema(value_type = Option, required = false)] pub name: Option>, #[serde(default, skip_serializing_if = "Option::is_none")] #[schema(value_type = String)] pub icon: Option, #[serde(default, skip_serializing_if = "Option::is_none")] #[schema(value_type = String)] pub color: Option, #[serde(default, skip_serializing_if = "Option::is_none")] #[schema(schema_with = super::int)] pub sort_order: Option, }