stry_common/models/
core.rs

1//! Base entities that are used internally and by other 'modules'.
2
3use crate::models::{blog::Post, story::Story, Existing};
4
5/// Universal site settings.
6#[rustfmt::skip]
7#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
8#[derive(serde::Deserialize, serde::Serialize)]
9pub struct Settings {
10    /// A unique setting name.
11    ///
12    /// Left as a [`String`] to allow for other modules to use the settings
13    /// without using extension types.
14    pub key: String,
15
16    /// The value of the key, encoded as JSON.
17    pub value: String,
18}
19
20/// A user of the website, used from displaying authors to signing in.
21#[rustfmt::skip]
22#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
23#[derive(serde::Deserialize, serde::Serialize)]
24pub struct User {
25    pub account: SettingsAccount,
26    pub site: SettingsSite,
27
28    /// Stores all the stories that the user owns.
29    ///
30    /// # Variant
31    ///
32    /// Is `None` when this type is used indirectly (ie in another entity).
33    pub stories: Option<Vec<Existing<Story>>>,
34
35    /// Stores all the blog posts that the user has.
36    ///
37    /// # Variant
38    ///
39    /// Is `None` when this type is used indirectly (ie in another entity).
40    pub posts: Option<Vec<Existing<Post>>>,
41}
42
43/// User settings for the user themself, ie name, biography, and security details.
44#[rustfmt::skip]
45#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
46#[derive(serde::Deserialize, serde::Serialize)]
47pub struct SettingsAccount {
48    /// The user's visible username.
49    ///
50    /// # Note
51    ///
52    /// Usernames are not unique, users are tracked with their `Id` only.
53    ///
54    /// Due to this, multiple users can have the same username. If possible
55    /// let the user choose which account they interact with instead of using
56    /// the first retrieved user.
57    pub name: String,
58
59    /// The user's email address.
60    ///
61    /// # Variant
62    ///
63    /// Is only `Some` when returned for login, a email change and for a user
64    /// profile 'view'.
65    pub email: Option<String>,
66
67    /// The hash of the user's password stored as bytes.
68    ///
69    /// # Variant
70    ///
71    /// This is only `Some` during a login attempt or password change.
72    pub hash: Option<Vec<u8>>,
73
74    /// The user's biography in parts.
75    ///
76    /// # Variant
77    ///
78    /// Is `None` if you aren't accessing a user profile 'view'.
79    pub biography: Option<Vec<Existing<Part>>>,
80}
81
82/// User settings for the site itself, ie appearance and notifications.
83// TODO: support color blindness
84#[rustfmt::skip]
85#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
86#[derive(serde::Deserialize, serde::Serialize)]
87pub struct SettingsSite {
88    pub theme: SiteTheme,
89}
90
91/// Website theme the user currently has selected, takes precedence over `prefers-color-scheme`.
92#[rustfmt::skip]
93#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
94#[derive(serde::Deserialize, serde::Serialize)]
95pub enum SiteTheme {
96    Dark,
97    Light,
98}
99
100/// A chapter or comment segment that can be commented on.
101///
102/// # Notes
103///
104/// Due to parts having comments and comments being made of parts,
105/// replies/comments could be nested.
106/// It is better to store them separately rather than the whole tree.
107#[rustfmt::skip]
108#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
109#[derive(serde::Deserialize, serde::Serialize)]
110pub struct Part {
111    pub kind: PartKind,
112
113    /// Any comments on or replying to the current part.
114    pub comments: Vec<Existing<Comment>>,
115}
116
117#[rustfmt::skip]
118#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
119#[derive(serde::Deserialize, serde::Serialize)]
120pub enum PartKind {
121    Heading { level: u8 },
122    Image { url: String, alt: Option<String>, },
123    Text { content: String, words: i64, },
124}
125
126/// A comment made of parts and comments that can be commented on.
127///
128/// # Notes
129///
130/// Due to parts having comments and comments being made of parts,
131/// replies/comments could be nested.
132/// It is better to store them separately rather than the whole tree.
133#[rustfmt::skip]
134#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
135#[derive(serde::Deserialize, serde::Serialize)]
136pub struct Comment {
137    pub author: Existing<User>,
138    pub main: Vec<Existing<Part>>,
139    pub children: Vec<Existing<Comment>>,
140}