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}