/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, fmt::Display, }; use crate::url_enum; #[rustfmt::skip] #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Default)] pub struct User { pub name: String, pub display_name: String, pub password: Vec, pub admin: bool, #[serde(default)] pub theme: Theme, #[serde(default)] pub player_preference: PlayerKind, #[serde(default)] pub native_secret: String, pub permissions: PermissionSet, } #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)] pub struct NodeUserData { pub watched: WatchedState, #[serde(default)] pub rating: i32, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Encode, Decode)] #[serde(rename_all = "snake_case")] pub enum WatchedState { None, Progress(f64), Watched, Pending, } url_enum!( #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] enum ApiWatchedState { None = "none", Watched = "watched", Pending = "pending", } ); #[derive(Debug, Serialize, Deserialize)] pub struct CreateSessionParams { pub username: String, pub password: String, pub expire: Option, pub drop_permissions: Option>, } url_enum!( #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)] #[serde(rename_all = "snake_case")] enum Theme { #[default] Dark = "dark", Light = "light", Purple = "purple", Black = "black", } ); url_enum!( #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)] #[serde(rename_all = "snake_case")] enum PlayerKind { #[default] Browser = "browser", Native = "native", NativeFullscreen = "native_fullscreen", } ); #[derive(Debug, Clone, Serialize, Deserialize, Default, Encode, Decode)] pub struct PermissionSet(pub HashMap); #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Encode, Decode)] #[serde(rename_all = "snake_case")] pub enum UserPermission { Admin, // ManageUsers, // GenerateInvite, ManageSelf, AccessNode(String), Transcode, FederatedContent, } impl UserPermission { pub const ALL_ENUMERABLE: &'static [UserPermission] = { use UserPermission::*; &[Admin, Transcode, ManageSelf, FederatedContent] }; pub fn default_value(&self) -> bool { use UserPermission::*; matches!(self, Transcode | ManageSelf | FederatedContent) } } impl Display for UserPermission { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(&match self { UserPermission::ManageSelf => "manage self (password, display name, etc.)".to_string(), UserPermission::FederatedContent => "access to federated content".to_string(), UserPermission::Admin => "administrative rights".to_string(), // UserPermission::StreamFormat(StreamFormat::Original) => { // "downloading the original media".to_string() // } // UserPermission::StreamFormat(StreamFormat::Matroska) => { // "downloading a remuxed WebM/Matroska version of the media ".to_string() // } // UserPermission::StreamFormat(x) => { // format!("downloading media via {x:?}") // } UserPermission::Transcode => "transcoding".to_string(), // UserPermission::ManageUsers => format!("management of all users"), // UserPermission::GenerateInvite => format!("inviting new users"), UserPermission::AccessNode(s) => format!("access to library node {s:?}"), }) } } impl Default for NodeUserData { fn default() -> Self { Self { watched: WatchedState::None, rating: 0, } } }