use rust_decimal::Decimal; use serde::{Deserialize, Serialize}; use std::str::FromStr; use thiserror::Error; #[derive( Serialize, Deserialize, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, sqlx::Type, )] #[serde(transparent)] #[sqlx(transparent)] pub struct StockName(String); impl From for StockName { fn from(s: String) -> Self { Self(s) } } #[derive(Error, Debug)] pub enum StockNameParseError {} impl FromStr for StockName { type Err = StockNameParseError; fn from_str(s: &str) -> Result { Ok(Self(s.to_string())) } } #[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)] #[serde(transparent)] pub struct StockSymbol(String); impl From for StockSymbol { fn from(s: String) -> Self { Self(s) } } #[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)] #[serde(transparent)] pub struct StockDescription(String); impl From for StockDescription { fn from(s: String) -> Self { Self(s) } } #[derive(Serialize, Deserialize, Copy, Clone, PartialEq, PartialOrd, Debug, Default)] #[serde(transparent)] pub struct StockPrice(Decimal); impl From for StockPrice { fn from(p: Decimal) -> Self { Self(p) } } #[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] pub struct Stock { name: StockName, symbol: StockSymbol, description: StockDescription, price: StockPrice, } impl Stock { pub fn new( name: impl Into, symbol: impl Into, description: impl Into, price: impl Into, ) -> Self { Self { name: name.into(), symbol: symbol.into(), description: description.into(), price: price.into(), } } }