style: 💄 improve comments and stringdocs
This commit is contained in:
parent
0557781373
commit
58b16834c8
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
/// 🐎 » market entity model
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||||
#[sea_orm(table_name = "market")]
|
#[sea_orm(table_name = "market")]
|
||||||
/// 🐎 » market entity model
|
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key, auto_increment = false)]
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
use sea_orm::entity::prelude::*;
|
use sea_orm::entity::prelude::*;
|
||||||
|
|
||||||
|
/// 🐎 » ticker entity model
|
||||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||||
#[sea_orm(table_name = "ticker")]
|
#[sea_orm(table_name = "ticker")]
|
||||||
/// 🐎 » ticker entity model
|
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
#[sea_orm(primary_key, auto_increment = false)]
|
#[sea_orm(primary_key, auto_increment = false)]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|||||||
@ -13,20 +13,24 @@ pub struct Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Service {
|
impl Service {
|
||||||
|
/// 🐎 » creates a new `Ticker` service
|
||||||
pub async fn new(conn: DatabaseConnection) -> Self {
|
pub async fn new(conn: DatabaseConnection) -> Self {
|
||||||
Self { conn }
|
Self { conn }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » retrieves all tickers from the database
|
||||||
pub async fn get_all(&self) -> Result<Vec<TickerModel>, DbErr> {
|
pub async fn get_all(&self) -> Result<Vec<TickerModel>, DbErr> {
|
||||||
let tickers = Ticker::find().all(&self.conn).await?;
|
let tickers = Ticker::find().all(&self.conn).await?;
|
||||||
Ok(tickers)
|
Ok(tickers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » retrieves a ticker from the database, given its id
|
||||||
pub async fn get(&self, id: String) -> Result<Option<TickerModel>, DbErr> {
|
pub async fn get(&self, id: String) -> Result<Option<TickerModel>, DbErr> {
|
||||||
let ticker = Ticker::find_by_id(id).one(&self.conn).await?;
|
let ticker = Ticker::find_by_id(id).one(&self.conn).await?;
|
||||||
Ok(ticker)
|
Ok(ticker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » retrieves a ticker from the database, given its symbol
|
||||||
pub async fn get_by_symbol(&self, symbol: String) -> Result<Option<TickerModel>, DbErr> {
|
pub async fn get_by_symbol(&self, symbol: String) -> Result<Option<TickerModel>, DbErr> {
|
||||||
let ticker =
|
let ticker =
|
||||||
Ticker::find().filter(ticker::Column::Symbol.eq(symbol)).one(&self.conn).await?;
|
Ticker::find().filter(ticker::Column::Symbol.eq(symbol)).one(&self.conn).await?;
|
||||||
@ -34,6 +38,7 @@ impl Service {
|
|||||||
Ok(ticker)
|
Ok(ticker)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » creates a new ticker in the database
|
||||||
pub async fn create(&self, market: TickerModel) -> Result<TickerModel, DbErr> {
|
pub async fn create(&self, market: TickerModel) -> Result<TickerModel, DbErr> {
|
||||||
Ticker::insert(market.clone().into_active_model()).exec(&self.conn).await?;
|
Ticker::insert(market.clone().into_active_model()).exec(&self.conn).await?;
|
||||||
Ok(market)
|
Ok(market)
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use {
|
|||||||
tonic::transport::Server,
|
tonic::transport::Server,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// the environment variable to set the gRPC server address
|
||||||
const RUSTLER_GRPC_API_ADDR: &str = "RUSTLER_GRPC_API_ADDR";
|
const RUSTLER_GRPC_API_ADDR: &str = "RUSTLER_GRPC_API_ADDR";
|
||||||
|
|
||||||
/// 🐎 » starts the rustler gRPC server
|
/// 🐎 » starts the rustler gRPC server
|
||||||
|
|||||||
@ -16,6 +16,7 @@ pub mod market_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Market {
|
impl Market {
|
||||||
|
/// 🐎 » converts a `Market` entity from gRPC to a database sea-orm `market::Model`
|
||||||
fn into_model(self) -> market::Model {
|
fn into_model(self) -> market::Model {
|
||||||
market::Model {
|
market::Model {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
@ -31,6 +32,7 @@ impl Market {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » converts a `market::Model` database entity to a gRPC `Market` entity
|
||||||
fn from_model(model: market::Model) -> Self {
|
fn from_model(model: market::Model) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: model.id,
|
id: model.id,
|
||||||
@ -67,6 +69,7 @@ impl GrpcServer {
|
|||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl MarketApi for GrpcServer {
|
impl MarketApi for GrpcServer {
|
||||||
|
/// retrieves and returns a market entity from the database, given its id
|
||||||
async fn get_all(&self, _: Request<Empty>) -> Result<Response<Markets>, Status> {
|
async fn get_all(&self, _: Request<Empty>) -> Result<Response<Markets>, Status> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let result = self.svc.get_all().await;
|
let result = self.svc.get_all().await;
|
||||||
@ -83,6 +86,7 @@ impl MarketApi for GrpcServer {
|
|||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// retrieves and returns all market entities from the database
|
||||||
async fn create(&self, market: Request<Market>) -> Result<Response<Market>, Status> {
|
async fn create(&self, market: Request<Market>) -> Result<Response<Market>, Status> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let mkt = market.into_inner().into_model();
|
let mkt = market.into_inner().into_model();
|
||||||
|
|||||||
@ -15,6 +15,7 @@ pub mod ticker_mod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ticker {
|
impl Ticker {
|
||||||
|
/// 🐎 » converts a `Ticker` entity from gRPC to a database sea-orm `ticker::Model`
|
||||||
fn into_model(self) -> ticker::Model {
|
fn into_model(self) -> ticker::Model {
|
||||||
ticker::Model {
|
ticker::Model {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
@ -23,6 +24,7 @@ impl Ticker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » converts a `ticker::Model` database entity to a gRPC `Ticker` entity
|
||||||
fn from_model(model: ticker::Model) -> Self {
|
fn from_model(model: ticker::Model) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: model.id,
|
id: model.id,
|
||||||
@ -52,6 +54,7 @@ impl GrpcServer {
|
|||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl TickerApi for GrpcServer {
|
impl TickerApi for GrpcServer {
|
||||||
|
/// retrieves and returns a ticker entity from the database, given its id
|
||||||
async fn get(&self, req: Request<TickerId>) -> Result<Response<Ticker>, Status> {
|
async fn get(&self, req: Request<TickerId>) -> Result<Response<Ticker>, Status> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let mkt = req.into_inner();
|
let mkt = req.into_inner();
|
||||||
@ -73,6 +76,7 @@ impl TickerApi for GrpcServer {
|
|||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// retrieves and returns all ticker entities from the database
|
||||||
async fn get_all(&self, _: Request<Empty>) -> Result<Response<Tickers>, Status> {
|
async fn get_all(&self, _: Request<Empty>) -> Result<Response<Tickers>, Status> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let result = self.svc.get_all().await;
|
let result = self.svc.get_all().await;
|
||||||
@ -89,6 +93,7 @@ impl TickerApi for GrpcServer {
|
|||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// creates a new ticker entity in the database
|
||||||
async fn create(&self, market: Request<Ticker>) -> Result<Response<Ticker>, Status> {
|
async fn create(&self, market: Request<Ticker>) -> Result<Response<Ticker>, Status> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let mkt = market.into_inner().into_model();
|
let mkt = market.into_inner().into_model();
|
||||||
|
|||||||
@ -5,6 +5,8 @@ use {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// 🐎 » bus **Publisher**
|
/// 🐎 » bus **Publisher**
|
||||||
|
///
|
||||||
|
/// allows to push a message or resource to the bus
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Publisher<RM: RedisMessage> {
|
pub struct Publisher<RM: RedisMessage> {
|
||||||
conn: MultiplexedConnection,
|
conn: MultiplexedConnection,
|
||||||
|
|||||||
@ -14,6 +14,8 @@ use {
|
|||||||
// https://github.com/exein-io/pulsar/blob/99ad35c8d13eaf1a37d7b6a9dcb812a5a1231d00/crates/pulsar-core/src/bus.rs
|
// https://github.com/exein-io/pulsar/blob/99ad35c8d13eaf1a37d7b6a9dcb812a5a1231d00/crates/pulsar-core/src/bus.rs
|
||||||
|
|
||||||
/// 🐎 » bus **Subscriber**
|
/// 🐎 » bus **Subscriber**
|
||||||
|
///
|
||||||
|
/// allows to subscribe to a redis key pattern and receive messages from the redis bus
|
||||||
pub struct Subscriber<RM: RedisMessage> {
|
pub struct Subscriber<RM: RedisMessage> {
|
||||||
// TODO: replace with storing tokio multiplexed connection like in publish.rs when redis@0.26.0
|
// TODO: replace with storing tokio multiplexed connection like in publish.rs when redis@0.26.0
|
||||||
// is released see https://github.com/redis-rs/redis-rs/issues/1137.
|
// is released see https://github.com/redis-rs/redis-rs/issues/1137.
|
||||||
@ -50,17 +52,33 @@ impl<RM: RedisMessage> Subscriber<RM> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » set the pattern to subscribe to
|
||||||
pub fn with_pattern(&mut self, pattern: &str) -> &mut Self {
|
pub fn with_pattern(&mut self, pattern: &str) -> &mut Self {
|
||||||
self.pattern = s!(pattern);
|
self.pattern = s!(pattern);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » returns the pattern used to subscribe to the redis bus, including the prefix if set
|
||||||
pub fn get_pattern(&self) -> String {
|
pub fn get_pattern(&self) -> String {
|
||||||
key(self.get_prefix(), self.pattern.clone())
|
key(self.get_prefix(), self.pattern.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 🐎 » subscribe to a channel
|
/// 🐎 » **stream**
|
||||||
pub async fn start_streaming(&mut self) -> Result<()> {
|
///
|
||||||
|
/// returns an `Observable` stream of messages from the redis bus
|
||||||
|
pub async fn stream(&mut self) -> Result<CloneableBoxOpThreads<RM, Infallible>> {
|
||||||
|
if self.subject.is_none() {
|
||||||
|
self.start_streaming().await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.subject.as_ref() {
|
||||||
|
Some(subject) => Ok(subject.clone().box_it()),
|
||||||
|
None => fail!("Could not start streaming messages from redis bus"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// subscribe to the redis feed
|
||||||
|
async fn start_streaming(&mut self) -> Result<()> {
|
||||||
if self.subject.is_none() {
|
if self.subject.is_none() {
|
||||||
self.subject = Some(SubjectThreads::default());
|
self.subject = Some(SubjectThreads::default());
|
||||||
}
|
}
|
||||||
@ -99,15 +117,4 @@ impl<RM: RedisMessage> Subscriber<RM> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn stream(&mut self) -> Result<CloneableBoxOpThreads<RM, Infallible>> {
|
|
||||||
if self.subject.is_none() {
|
|
||||||
self.start_streaming().await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.subject.as_ref() {
|
|
||||||
Some(subject) => Ok(subject.clone().box_it()),
|
|
||||||
None => fail!("Could not start streaming messages from redis bus"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ use {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// 🐎 » a struct representing the status of a rustler at a given time
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
pub enum RustlerStatus {
|
pub enum RustlerStatus {
|
||||||
Connecting,
|
Connecting,
|
||||||
@ -23,6 +24,7 @@ pub enum RustlerStatus {
|
|||||||
Disconnected,
|
Disconnected,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » an enum representing the different types of market hours
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum MarketHourType {
|
pub enum MarketHourType {
|
||||||
Pre = 0,
|
Pre = 0,
|
||||||
@ -49,6 +51,8 @@ impl From<u8> for MarketHourType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 🐎 » a struct storing a ticker's quote at a given time, and the change in price since the last
|
||||||
|
/// quote
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Quote {
|
pub struct Quote {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
@ -93,6 +97,9 @@ impl ToRedisKey for Quote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ToFromRedisMessage for Quote {
|
impl ToFromRedisMessage for Quote {
|
||||||
|
/// 🐎 » converts a `Quote` to a serialized message that can be sent over a redis channel
|
||||||
|
///
|
||||||
|
/// the message is in the format `id¦market¦price¦change_percent¦time¦market_hours`
|
||||||
fn as_message(&self) -> String {
|
fn as_message(&self) -> String {
|
||||||
// id¦market¦price¦change_percent¦time¦market_hours
|
// id¦market¦price¦change_percent¦time¦market_hours
|
||||||
format!(
|
format!(
|
||||||
@ -349,6 +356,9 @@ pub trait Rustler: RustlerAccessor + Send + Sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// macro that expands to the accessor functions for a `Rustler` struct
|
||||||
|
///
|
||||||
|
/// for internal use
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! rustler_accessors {
|
macro_rules! rustler_accessors {
|
||||||
(
|
(
|
||||||
|
|||||||
@ -80,6 +80,7 @@ impl RustlerJar {
|
|||||||
self.rustlers.get(key)
|
self.rustlers.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// get the mutable Rustler for the given market as a mutable reference
|
||||||
pub fn get_mut(&mut self, market: &market::Model) -> Option<&mut Arc<Mutex<Box<dyn Rustler>>>> {
|
pub fn get_mut(&mut self, market: &market::Model) -> Option<&mut Arc<Mutex<Box<dyn Rustler>>>> {
|
||||||
let key = self.get_key(market).to_owned();
|
let key = self.get_key(market).to_owned();
|
||||||
self.rustlers.get_mut(&key)
|
self.rustlers.get_mut(&key)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user