use serde::{Deserialize, Serialize}; use sqlx::{error::BoxDynError, Decode, Encode, FromRow, Postgres, Type}; use std::ops::Deref; use time::OffsetDateTime; macro_rules! impl_apca_sqlx_traits { ($outer_type:ident, $inner_type:path, $fallback:expr) => { #[derive(Clone, Debug, Copy, PartialEq, Serialize, Deserialize)] pub struct $outer_type($inner_type); impl Deref for $outer_type { type Target = $inner_type; fn deref(&self) -> &Self::Target { &self.0 } } impl From<$inner_type> for $outer_type { fn from(inner: $inner_type) -> Self { $outer_type(inner) } } impl From for $outer_type { fn from(s: String) -> Self { s.parse().unwrap_or($fallback).into() } } impl Decode<'_, Postgres> for $outer_type { fn decode( value: >::ValueRef, ) -> Result { Ok($outer_type::from(>::decode( value, )?)) } } impl Encode<'_, Postgres> for $outer_type { fn encode_by_ref( &self, buf: &mut >::ArgumentBuffer, ) -> sqlx::encode::IsNull { >::encode_by_ref(&self.0.as_ref().into(), buf) } } impl Type for $outer_type { fn type_info() -> ::TypeInfo { >::type_info() } } }; } impl_apca_sqlx_traits!( Class, apca::api::v2::asset::Class, apca::api::v2::asset::Class::Unknown ); impl_apca_sqlx_traits!( Exchange, apca::api::v2::asset::Exchange, apca::api::v2::asset::Exchange::Unknown ); #[derive(Clone, Debug, PartialEq, FromRow, Serialize, Deserialize)] pub struct Asset { pub symbol: String, pub class: Class, pub exchange: Exchange, pub trading: bool, pub date_added: OffsetDateTime, } #[derive(Clone, Debug, PartialEq, FromRow, Serialize, Deserialize)] pub struct Bar { pub timestamp: OffsetDateTime, pub asset_symbol: String, pub open: f64, pub high: f64, pub low: f64, pub close: f64, pub volume: f64, }