tetratto-core 12.0.0

The core behind Tetratto
Documentation
use std::fmt::Display;

use serde::{Serialize, Deserialize};
use tetratto_shared::{snow::Snowflake, unix_epoch_timestamp};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Product {
    pub id: usize,
    pub created: usize,
    pub owner: usize,
    pub name: String,
    pub description: String,
    pub likes: isize,
    pub dislikes: isize,
    pub product_type: ProductType,
    pub price: ProductPrice,
    /// Optional uploads to accompany the product title and description. Maximum of 4.
    pub uploads: Vec<usize>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ProductType {
    /// Text + images.
    Data,
    /// When a commission product is purchased, the creator will receive a request
    /// prompting them to respond with text + images.
    ///
    /// This is the only product type which does not immediately return data to the
    /// customer, as seller input is required.
    ///
    /// If the request is deleted, the purchase should be immediately refunded.
    ///
    /// Commissions are paid beforehand to prevent theft. This means it is vital
    /// that refunds are enforced.
    Commission,
}

/// A currency.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Currency {
    USD,
    EUR,
    GBP,
}

impl Display for Currency {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(match self {
            Currency::USD => "$",
            Currency::EUR => "",
            Currency::GBP => "£",
        })
    }
}

/// Price in USD. `(dollars, cents)`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProductPrice(u64, u64, Currency);

impl Display for ProductPrice {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(&format!("{}{}.{}", self.2, self.0, self.1))
    }
}

impl Product {
    /// Create a new [`Product`].
    pub fn new(
        owner: usize,
        name: String,
        description: String,
        price: ProductPrice,
        r#type: ProductType,
    ) -> Self {
        Self {
            id: Snowflake::new().to_string().parse::<usize>().unwrap(),
            created: unix_epoch_timestamp(),
            owner,
            name,
            description,
            likes: 0,
            dislikes: 0,
            product_type: r#type,
            price,
            uploads: Vec::new(),
        }
    }
}