pslink_shared/
datatypes.rs

1//! The more generic datatypes used in pslink
2use std::ops::Deref;
3
4use serde::{Deserialize, Serialize, Serializer};
5use strum_macros::{AsRefStr, EnumIter, EnumString, ToString};
6
7use crate::apirequests::users::Role;
8/// A generic list returntype containing the User and a Vec containing e.g. Links or Users
9#[derive(Clone, Deserialize, Serialize)]
10pub struct ListWithOwner<T> {
11    pub user: User,
12    pub list: Vec<T>,
13}
14
15/// A link together with its author and its click-count.
16#[derive(Clone, Deserialize, Serialize, Debug)]
17pub struct FullLink {
18    pub link: Link,
19    pub user: User,
20    pub clicks: Count,
21}
22
23/// A User of the pslink service
24#[derive(PartialEq, Serialize, Deserialize, Clone, Debug)]
25pub struct User {
26    pub id: i64,
27    pub username: String,
28    pub email: String,
29    pub password: Secret,
30    pub role: Role,
31    pub language: Lang,
32}
33
34/// A short url of the link service
35#[derive(Serialize, Deserialize, Clone, Debug)]
36pub struct Link {
37    pub id: i64,
38    pub title: String,
39    pub target: String,
40    pub code: String,
41    pub author: i64,
42    pub created_at: chrono::NaiveDateTime,
43}
44
45/// When statistics are counted
46#[derive(Serialize, Deserialize, Clone, Debug)]
47pub struct Count {
48    pub number: i32,
49}
50
51/// Everytime a shor url is clicked record it for statistical evaluation.
52#[derive(Serialize, Debug)]
53pub struct Click {
54    pub id: i64,
55    pub link: i64,
56    pub created_at: chrono::NaiveDateTime,
57}
58
59/// The Password: Display, Debug and serialize do not include the Password to prevent leaks of sensible information in logs or similar.
60#[derive(PartialEq, Clone, Deserialize)]
61#[serde(from = "String")]
62pub struct Secret {
63    pub secret: Option<String>,
64}
65
66impl From<String> for Secret {
67    fn from(_: String) -> Self {
68        Self { secret: None }
69    }
70}
71
72impl Serialize for Secret {
73    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74    where
75        S: Serializer,
76    {
77        serializer.serialize_str("*****SECRET*****")
78    }
79}
80
81impl Secret {
82    #[must_use]
83    pub const fn new(secret: String) -> Self {
84        Self {
85            secret: Some(secret),
86        }
87    }
88}
89
90impl std::fmt::Debug for Secret {
91    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        f.write_str("*****SECRET*****")
93    }
94}
95
96impl std::fmt::Display for Secret {
97    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98        f.write_str("*****SECRET*****")
99    }
100}
101
102/// Loadable is a type that has not been loaded but will be in future. It can be used to indicate the loading process.
103#[derive(Debug, Serialize, Deserialize, Clone)]
104pub enum Loadable<T> {
105    Data(Option<T>),
106    Loading,
107}
108
109impl<T> Deref for Loadable<T> {
110    type Target = Option<T>;
111
112    fn deref(&self) -> &Self::Target {
113        match self {
114            Loadable::Data(t) => t,
115            Loadable::Loading => &None,
116        }
117    }
118}
119
120/// An `enum` containing the available languages.
121/// To add an additional language add it to this enum aswell as an appropriate file into the locales folder.
122#[allow(clippy::upper_case_acronyms)]
123#[derive(
124    Debug,
125    Copy,
126    Clone,
127    EnumIter,
128    EnumString,
129    ToString,
130    AsRefStr,
131    Eq,
132    PartialEq,
133    Serialize,
134    Deserialize,
135)]
136pub enum Lang {
137    #[strum(serialize = "en-US", serialize = "en", serialize = "enUS")]
138    EnUS,
139    #[strum(serialize = "de-DE", serialize = "de", serialize = "deDE")]
140    DeDE,
141}