use std::time::SystemTime; use serde::{Deserialize, Serialize}; #[cfg(feature = "ssr")] use diesel::prelude::*; // These "models" are used to represent the data in the database // Diesel uses these models to generate the SQL queries that are used to interact with the database. // These types are also used for API endpoints, for consistency. Because the file must be compiled // for both the server and the client, we use the `cfg_attr` attribute to conditionally add // diesel-specific attributes to the models when compiling for the server /// Model for a "User", used for querying the database #[cfg_attr(feature = "ssr", derive(Queryable, Selectable))] #[cfg_attr(feature = "ssr", diesel(table_name = crate::schema::users))] #[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))] #[derive(Serialize, Deserialize)] pub struct User { /// A unique id for the user pub id: i32, /// The user's username pub username: String, /// The user's email pub email: String, /// The user's password, stored as a hash pub password: String, /// The time the user was created pub created_at: SystemTime, } /// Model for a "New User", used for inserting into the database /// Note that this model does not have an id or created_at field, as those are automatically /// generated by the database and we don't want to deal with them ourselves #[cfg_attr(feature = "ssr", derive(Insertable))] #[cfg_attr(feature = "ssr", diesel(table_name = crate::schema::users))] #[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))] #[derive(Serialize, Deserialize, Clone, Debug)] pub struct NewUser { /// The user's username pub username: String, /// The user's email pub email: String, /// The user's password, stored as a hash pub password: String, } /// Convert a User into a NewUser, omitting the id and created_at fields impl From for NewUser { fn from(user: User) -> NewUser { NewUser { username: user.username, email: user.email, password: user.password, } } } /// Model for a "Public User", used for returning user data to the client /// This model omits the password field, so that the hashed password is not sent to the client #[cfg_attr(feature = "ssr", derive(Queryable, Selectable))] #[cfg_attr(feature = "ssr", diesel(table_name = crate::schema::users))] #[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))] #[derive(Serialize, Deserialize)] pub struct PublicUser { /// A unique id for the user pub id: i32, /// The user's username pub username: String, /// The user's email pub email: String, /// The time the user was created pub created_at: SystemTime, } /// Convert a User into a PublicUser, omitting the password field impl From for PublicUser { fn from(user: User) -> PublicUser { PublicUser { id: user.id, username: user.username, email: user.email, created_at: user.created_at, } } }