2022-05-06 11:47:18 +02:00
|
|
|
#![feature(drain_filter)]
|
|
|
|
|
|
|
|
pub mod api;
|
|
|
|
|
2022-05-08 09:47:05 +02:00
|
|
|
#[cfg(feature = "dummy")]
|
|
|
|
mod dummy;
|
|
|
|
pub mod encrypt;
|
|
|
|
|
2022-05-06 11:47:18 +02:00
|
|
|
use std::fmt::Formatter;
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
use derive_more::{Deref, Display, From};
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg(feature = "dummy")]
|
|
|
|
use fake::Fake;
|
2022-05-08 09:47:05 +02:00
|
|
|
use rand::Rng;
|
2022-05-06 11:47:18 +02:00
|
|
|
use serde::de::{Error, Visitor};
|
|
|
|
use serde::{Deserialize, Deserializer, Serialize};
|
|
|
|
|
2022-05-08 09:47:05 +02:00
|
|
|
pub use crate::encrypt::*;
|
|
|
|
|
2022-05-06 11:47:18 +02:00
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
|
|
pub enum TransformError {
|
|
|
|
#[error("Given value is below minimal value")]
|
|
|
|
BelowMinimal,
|
|
|
|
#[error("Given value is not valid day flag")]
|
|
|
|
NotDay,
|
|
|
|
#[error("Given value is not valid email address")]
|
|
|
|
NotEmail,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub type RecordId = i32;
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename_all = "snake_case"))]
|
|
|
|
#[derive(Copy, Clone, Debug, Display, Deserialize, Serialize)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum OrderStatus {
|
|
|
|
#[display(fmt = "Potwierdzone")]
|
|
|
|
Confirmed,
|
|
|
|
#[display(fmt = "Odebrane")]
|
|
|
|
Delivered,
|
|
|
|
#[display(fmt = "Opłacone")]
|
|
|
|
Payed,
|
|
|
|
#[display(fmt = "Anulowane")]
|
|
|
|
Cancelled,
|
|
|
|
#[display(fmt = "Wymaga zwrotu płatności")]
|
|
|
|
RequireRefund,
|
|
|
|
#[display(fmt = "Płatność zwrócona")]
|
|
|
|
Refunded,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename_all = "snake_case"))]
|
|
|
|
#[derive(Copy, Clone, Debug, Display, Deserialize, Serialize, PartialEq)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum Role {
|
|
|
|
#[display(fmt = "Adminitrator")]
|
|
|
|
Admin,
|
|
|
|
#[display(fmt = "Użytkownik")]
|
|
|
|
User,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq<&str> for Role {
|
|
|
|
fn eq(&self, other: &&str) -> bool {
|
|
|
|
self.as_str() == *other
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Role {
|
|
|
|
pub fn as_str(&self) -> &str {
|
|
|
|
match self {
|
|
|
|
Role::Admin => "Admin",
|
|
|
|
Role::User => "User",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[derive(Copy, Clone, Debug, Display, Deserialize, Serialize)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum QuantityUnit {
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename = "g"))]
|
|
|
|
Gram,
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename = "dkg"))]
|
|
|
|
Decagram,
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename = "kg"))]
|
|
|
|
Kilogram,
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename = "piece"))]
|
|
|
|
Piece,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename_all = "snake_case"))]
|
|
|
|
#[derive(Copy, Clone, Debug, Display, Deserialize, Serialize)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum PaymentMethod {
|
|
|
|
PayU,
|
|
|
|
PaymentOnTheSpot,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename_all = "snake_case"))]
|
|
|
|
#[derive(Copy, Clone, Debug, Display, Deserialize, Serialize)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum ShoppingCartState {
|
|
|
|
Active,
|
|
|
|
Closed,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename_all = "snake_case"))]
|
|
|
|
#[derive(Copy, Clone, Debug, Display, Deserialize, Serialize, PartialEq)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum Audience {
|
|
|
|
Web,
|
|
|
|
Mobile,
|
|
|
|
Feed,
|
|
|
|
AdminPanel,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PartialEq<&str> for Audience {
|
|
|
|
fn eq(&self, other: &&str) -> bool {
|
|
|
|
self.as_str() == *other
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Audience {
|
|
|
|
pub fn as_str(&self) -> &str {
|
|
|
|
match self {
|
|
|
|
Audience::Web => "Web",
|
|
|
|
Audience::Mobile => "Mobile",
|
|
|
|
Audience::Feed => "Feed",
|
|
|
|
Audience::AdminPanel => "AdminPanel",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(rename_all = "snake_case"))]
|
|
|
|
#[derive(Copy, Clone, Debug, Display, Deserialize, Serialize, PartialEq)]
|
|
|
|
#[serde(rename_all = "snake_case")]
|
|
|
|
pub enum AccountState {
|
|
|
|
Active,
|
|
|
|
Suspended,
|
|
|
|
Banned,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Audience {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::Web
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Default, Debug, Copy, Clone, Deref, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Price(NonNegative);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Default, Debug, Copy, Clone, Deref, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Quantity(NonNegative);
|
|
|
|
|
|
|
|
impl TryFrom<i32> for Quantity {
|
|
|
|
type Error = TransformError;
|
|
|
|
|
|
|
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
|
|
Ok(Self(value.try_into()?))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Deserialize, Serialize, Debug, Deref, From, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Login(String);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Debug, Deref, From, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Email(String);
|
|
|
|
|
|
|
|
impl FromStr for Email {
|
|
|
|
type Err = TransformError;
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
if validator::validate_email(s) {
|
|
|
|
Ok(Self(String::from(s)))
|
|
|
|
} else {
|
|
|
|
Err(TransformError::NotEmail)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'de> serde::Deserialize<'de> for Email {
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
{
|
|
|
|
struct EmailVisitor {}
|
|
|
|
impl<'v> Visitor<'v> for EmailVisitor {
|
|
|
|
type Value = String;
|
|
|
|
|
|
|
|
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
|
|
|
|
formatter.write_str("valid e-mail address")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: Error,
|
|
|
|
{
|
|
|
|
if validator::validate_email(s) {
|
|
|
|
Ok(String::from(s))
|
|
|
|
} else {
|
|
|
|
Err(E::custom("this is not email address"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(Email(deserializer.deserialize_str(EmailVisitor {})?))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Default, Debug, Copy, Clone, Deref, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct NonNegative(i32);
|
|
|
|
|
|
|
|
impl TryFrom<i32> for NonNegative {
|
|
|
|
type Error = TransformError;
|
|
|
|
|
|
|
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
|
|
if value < 0 {
|
|
|
|
Err(TransformError::BelowMinimal)
|
|
|
|
} else {
|
|
|
|
Ok(Self(value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'de> serde::Deserialize<'de> for NonNegative {
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
where
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
{
|
|
|
|
struct NonNegativeVisitor;
|
|
|
|
impl<'v> Visitor<'v> for NonNegativeVisitor {
|
|
|
|
type Value = i32;
|
|
|
|
|
|
|
|
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
|
|
|
|
formatter.write_str("value equal or greater than 0")
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: Error,
|
|
|
|
{
|
|
|
|
if v >= 0 {
|
|
|
|
Ok(v)
|
|
|
|
} else {
|
|
|
|
Err(E::custom("Value must be equal or greater than 0"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: Error,
|
|
|
|
{
|
|
|
|
let v = v
|
|
|
|
.try_into()
|
|
|
|
.map_err(|_| E::custom("Value must be equal or greater than 0"))?;
|
|
|
|
if v >= 0 {
|
|
|
|
Ok(v)
|
|
|
|
} else {
|
|
|
|
Err(E::custom("Value must be equal or greater than 0"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: Error,
|
|
|
|
{
|
|
|
|
let v = v
|
|
|
|
.try_into()
|
|
|
|
.map_err(|_| E::custom("Value must be equal or greater than 0"))?;
|
|
|
|
Ok(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
|
|
|
where
|
|
|
|
E: Error,
|
|
|
|
{
|
|
|
|
let v = v
|
|
|
|
.try_into()
|
|
|
|
.map_err(|_| E::custom("Value must be equal or greater than 0"))?;
|
|
|
|
Ok(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(NonNegative(
|
|
|
|
deserializer.deserialize_i32(NonNegativeVisitor)?,
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Display, From)]
|
|
|
|
#[serde(rename_all = "lowercase")]
|
|
|
|
pub enum Day {
|
|
|
|
Monday = 1 << 0,
|
|
|
|
Tuesday = 1 << 1,
|
|
|
|
Wednesday = 1 << 2,
|
|
|
|
Thursday = 1 << 3,
|
|
|
|
Friday = 1 << 4,
|
|
|
|
Saturday = 1 << 5,
|
|
|
|
Sunday = 1 << 6,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl TryFrom<i32> for Day {
|
|
|
|
type Error = TransformError;
|
|
|
|
|
|
|
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
|
|
if value == (Day::Monday as i32) {
|
|
|
|
Ok(Day::Monday)
|
|
|
|
} else if value == (Day::Tuesday as i32) {
|
|
|
|
Ok(Day::Tuesday)
|
|
|
|
} else if value == (Day::Wednesday as i32) {
|
|
|
|
Ok(Day::Wednesday)
|
|
|
|
} else if value == (Day::Thursday as i32) {
|
|
|
|
Ok(Day::Thursday)
|
|
|
|
} else if value == (Day::Friday as i32) {
|
|
|
|
Ok(Day::Friday)
|
|
|
|
} else if value == (Day::Saturday as i32) {
|
|
|
|
Ok(Day::Saturday)
|
|
|
|
} else if value == (Day::Sunday as i32) {
|
|
|
|
Ok(Day::Sunday)
|
|
|
|
} else {
|
|
|
|
Err(TransformError::NotDay)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[derive(Serialize, Deserialize, Deref, Debug)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Days(Vec<Day>);
|
|
|
|
|
|
|
|
#[cfg(feature = "db")]
|
|
|
|
impl<'q> ::sqlx::encode::Encode<'q, sqlx::Postgres> for Days
|
|
|
|
where
|
|
|
|
i32: ::sqlx::encode::Encode<'q, sqlx::Postgres>,
|
|
|
|
{
|
|
|
|
fn encode_by_ref(
|
|
|
|
&self,
|
|
|
|
buf: &mut <sqlx::Postgres as ::sqlx::database::HasArguments<'q>>::ArgumentBuffer,
|
|
|
|
) -> ::sqlx::encode::IsNull {
|
|
|
|
let value = self.0.iter().fold(1, |memo, v| memo | *v as i32);
|
|
|
|
|
|
|
|
<i32 as ::sqlx::encode::Encode<sqlx::Postgres>>::encode_by_ref(&value, buf)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> usize {
|
|
|
|
<i32 as ::sqlx::encode::Encode<sqlx::Postgres>>::size_hint(&Default::default())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "db")]
|
|
|
|
impl<'r> ::sqlx::decode::Decode<'r, sqlx::Postgres> for Days
|
|
|
|
where
|
|
|
|
i32: ::sqlx::decode::Decode<'r, sqlx::Postgres>,
|
|
|
|
{
|
|
|
|
fn decode(
|
|
|
|
value: <sqlx::Postgres as ::sqlx::database::HasValueRef<'r>>::ValueRef,
|
|
|
|
) -> ::std::result::Result<
|
|
|
|
Self,
|
|
|
|
::std::boxed::Box<
|
|
|
|
dyn ::std::error::Error + 'static + ::std::marker::Send + ::std::marker::Sync,
|
|
|
|
>,
|
|
|
|
> {
|
|
|
|
let value = <i32 as ::sqlx::decode::Decode<'r, sqlx::Postgres>>::decode(value)?;
|
|
|
|
Ok(Days(
|
|
|
|
(0..9)
|
|
|
|
.into_iter()
|
|
|
|
.filter_map(|n| {
|
|
|
|
eprintln!(
|
|
|
|
"d {} {} {} {:?}",
|
|
|
|
n,
|
|
|
|
1 << n,
|
|
|
|
value & 1 << n,
|
|
|
|
Day::try_from(value & 1 << n).ok()
|
|
|
|
);
|
|
|
|
Day::try_from(value & 1 << n).ok()
|
|
|
|
})
|
|
|
|
.collect(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "db")]
|
|
|
|
impl sqlx::Type<sqlx::Postgres> for Days
|
|
|
|
where
|
|
|
|
i32: ::sqlx::Type<sqlx::Postgres>,
|
|
|
|
{
|
|
|
|
fn type_info() -> <sqlx::Postgres as ::sqlx::Database>::TypeInfo {
|
|
|
|
<i32 as ::sqlx::Type<sqlx::Postgres>>::type_info()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn compatible(ty: &<sqlx::Postgres as ::sqlx::Database>::TypeInfo) -> bool {
|
|
|
|
<i32 as ::sqlx::Type<sqlx::Postgres>>::compatible(ty)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Deref, From, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct Password(String);
|
|
|
|
|
2022-05-08 09:47:05 +02:00
|
|
|
impl Password {
|
|
|
|
pub fn new<S: Into<String>>(pass: S) -> Self {
|
|
|
|
Self(pass.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Deref, From, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct PasswordConfirmation(String);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Deref, From, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct PassHash(String);
|
|
|
|
|
|
|
|
impl PartialEq<PasswordConfirmation> for Password {
|
|
|
|
fn eq(&self, other: &PasswordConfirmation) -> bool {
|
|
|
|
self.0 == other.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Deref, Display, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct AccountId(RecordId);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
2022-05-08 09:47:05 +02:00
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
2022-05-06 11:47:18 +02:00
|
|
|
pub struct FullAccount {
|
|
|
|
pub id: AccountId,
|
|
|
|
pub email: Email,
|
|
|
|
pub login: Login,
|
|
|
|
pub pass_hash: PassHash,
|
|
|
|
pub role: Role,
|
|
|
|
pub customer_id: uuid::Uuid,
|
|
|
|
pub state: AccountState,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Account {
|
|
|
|
pub id: AccountId,
|
|
|
|
pub email: Email,
|
|
|
|
pub login: Login,
|
|
|
|
pub role: Role,
|
|
|
|
pub customer_id: uuid::Uuid,
|
|
|
|
pub state: AccountState,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<FullAccount> for Account {
|
|
|
|
fn from(
|
|
|
|
FullAccount {
|
|
|
|
id,
|
|
|
|
email,
|
|
|
|
login,
|
|
|
|
pass_hash: _,
|
|
|
|
role,
|
|
|
|
customer_id,
|
|
|
|
state,
|
|
|
|
}: FullAccount,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
id,
|
|
|
|
email,
|
|
|
|
login,
|
|
|
|
role,
|
|
|
|
customer_id,
|
|
|
|
state,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash, Deref, Display, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct ProductId(RecordId);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct ProductName(String);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct ProductShortDesc(String);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct ProductLongDesc(String);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone, Deref, Display, From)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct ProductCategory(String);
|
|
|
|
|
2022-05-08 09:47:05 +02:00
|
|
|
impl ProductCategory {
|
|
|
|
pub fn new<S: Into<String>>(s: S) -> Self {
|
|
|
|
Self(s.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
2022-05-08 09:47:05 +02:00
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
2022-05-06 11:47:18 +02:00
|
|
|
pub struct Product {
|
|
|
|
pub id: ProductId,
|
|
|
|
pub name: ProductName,
|
|
|
|
pub short_description: ProductShortDesc,
|
|
|
|
pub long_description: ProductLongDesc,
|
|
|
|
pub category: Option<ProductCategory>,
|
|
|
|
pub price: Price,
|
|
|
|
pub deliver_days_flag: Days,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct StockId(pub RecordId);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Stock {
|
|
|
|
pub id: StockId,
|
|
|
|
pub product_id: ProductId,
|
|
|
|
pub quantity: Quantity,
|
|
|
|
pub quantity_unit: QuantityUnit,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Display, Deref)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct AccountOrderId(RecordId);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Display, Deref)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct OrderId(String);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct AccountOrder {
|
|
|
|
pub id: AccountOrderId,
|
|
|
|
pub buyer_id: AccountId,
|
|
|
|
pub status: OrderStatus,
|
|
|
|
pub order_id: Option<OrderId>,
|
|
|
|
pub order_ext_id: uuid::Uuid,
|
|
|
|
pub service_order_id: Option<String>,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct PublicAccountOrder {
|
|
|
|
pub id: AccountOrderId,
|
|
|
|
pub buyer_id: AccountId,
|
|
|
|
pub status: OrderStatus,
|
|
|
|
pub order_id: Option<OrderId>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<AccountOrder> for PublicAccountOrder {
|
|
|
|
fn from(
|
|
|
|
AccountOrder {
|
|
|
|
id,
|
|
|
|
buyer_id,
|
|
|
|
status,
|
|
|
|
order_id,
|
|
|
|
order_ext_id: _,
|
|
|
|
service_order_id: _,
|
|
|
|
}: AccountOrder,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
id,
|
|
|
|
buyer_id,
|
|
|
|
status,
|
|
|
|
order_id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Deref)]
|
|
|
|
pub struct OrderItemId(pub RecordId);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
|
pub struct OrderItem {
|
|
|
|
pub id: OrderItemId,
|
|
|
|
pub product_id: ProductId,
|
|
|
|
pub order_id: AccountOrderId,
|
|
|
|
pub quantity: Quantity,
|
|
|
|
pub quantity_unit: QuantityUnit,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Deref, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct ShoppingCartId(pub RecordId);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ShoppingCart {
|
|
|
|
pub id: ShoppingCartId,
|
|
|
|
pub buyer_id: AccountId,
|
|
|
|
pub payment_method: PaymentMethod,
|
|
|
|
pub state: ShoppingCartState,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Deref, Display)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct ShoppingCartItemId(RecordId);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ShoppingCartItem {
|
|
|
|
pub id: ShoppingCartId,
|
|
|
|
pub product_id: ProductId,
|
|
|
|
pub shopping_cart_id: ShoppingCartId,
|
|
|
|
pub quantity: Quantity,
|
|
|
|
pub quantity_unit: QuantityUnit,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ShoppingCartItem {
|
|
|
|
pub fn quantity(&self) -> Quantity {
|
|
|
|
self.quantity
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Deref, Display, Debug)]
|
|
|
|
#[serde(transparent)]
|
|
|
|
pub struct TokenId(RecordId);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Token {
|
|
|
|
pub id: TokenId,
|
|
|
|
pub customer_id: uuid::Uuid,
|
|
|
|
pub role: Role,
|
|
|
|
/// iss (issuer): Issuer of the JWT
|
|
|
|
pub issuer: String,
|
|
|
|
/// sub (subject): Subject of the JWT (the user)
|
|
|
|
pub subject: i32,
|
|
|
|
/// aud (audience): Recipient for which the JWT is intended
|
|
|
|
pub audience: Audience,
|
|
|
|
/// exp (expiration time): Time after which the JWT expires
|
|
|
|
pub expiration_time: chrono::NaiveDateTime,
|
|
|
|
/// nbt (not before time): Time before which the JWT must not be accepted
|
|
|
|
/// for processing
|
|
|
|
pub not_before_time: chrono::NaiveDateTime,
|
|
|
|
/// iat (issued at time): Time at which the JWT was issued; can be used to
|
|
|
|
/// determine age of the JWT,
|
|
|
|
pub issued_at_time: chrono::NaiveDateTime,
|
|
|
|
/// jti (JWT ID): Unique identifier; can be used to prevent the JWT from
|
|
|
|
/// being replayed (allows a token to be used only once)
|
|
|
|
pub jwt_id: uuid::Uuid,
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Deref, Display, From)]
|
|
|
|
pub struct TokenString(String);
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Deref, Display, From)]
|
|
|
|
pub struct LocalPath(String);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
2022-05-06 11:47:18 +02:00
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Deref, Display, From)]
|
|
|
|
pub struct FileName(String);
|
2022-05-06 16:02:38 +02:00
|
|
|
|
2022-05-08 09:47:05 +02:00
|
|
|
impl FileName {
|
|
|
|
pub fn new<S: Into<String>>(s: S) -> Self {
|
|
|
|
Self(s.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-06 16:02:38 +02:00
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
2022-05-08 09:47:05 +02:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Deref, Display, From)]
|
2022-05-06 16:02:38 +02:00
|
|
|
pub struct PhotoId(RecordId);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::Type))]
|
|
|
|
#[cfg_attr(feature = "db", sqlx(transparent))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Deref, Display, From)]
|
|
|
|
pub struct ProductPhotoId(RecordId);
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
|
pub struct Photo {
|
|
|
|
pub id: PhotoId,
|
|
|
|
pub local_path: LocalPath,
|
|
|
|
pub file_name: FileName,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "dummy", derive(fake::Dummy))]
|
|
|
|
#[cfg_attr(feature = "db", derive(sqlx::FromRow))]
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
|
pub struct ProductPhoto {
|
|
|
|
pub id: ProductPhotoId,
|
|
|
|
pub product_id: ProductId,
|
|
|
|
pub photo_id: PhotoId,
|
|
|
|
}
|