Files
qrust/backend/src/types.rs
2024-01-25 17:15:51 +00:00

89 lines
2.4 KiB
Rust

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<String> for $outer_type {
fn from(s: String) -> Self {
s.parse().unwrap_or($fallback).into()
}
}
impl Decode<'_, Postgres> for $outer_type {
fn decode(
value: <Postgres as sqlx::database::HasValueRef<'_>>::ValueRef,
) -> Result<Self, BoxDynError> {
Ok($outer_type::from(<String as Decode<Postgres>>::decode(
value,
)?))
}
}
impl Encode<'_, Postgres> for $outer_type {
fn encode_by_ref(
&self,
buf: &mut <Postgres as sqlx::database::HasArguments<'_>>::ArgumentBuffer,
) -> sqlx::encode::IsNull {
<String as Encode<Postgres>>::encode_by_ref(&self.0.as_ref().into(), buf)
}
}
impl Type<Postgres> for $outer_type {
fn type_info() -> <Postgres as sqlx::Database>::TypeInfo {
<String as Type<Postgres>>::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,
}