use crate::messages::{encode_protobuf_message, encode_raw_length, OutgoingMessages};
use prost::Message;
pub(crate) trait ResponseEncoder {
fn fields(&self) -> Vec<String>;
fn encode_pipe(&self) -> String {
join_fields(&self.fields(), '|')
}
fn encode_null(&self) -> String {
join_fields(&self.fields(), '\0')
}
fn encode_length_prefixed(&self) -> Vec<u8> {
encode_raw_length(self.encode_null().as_bytes())
}
}
pub(crate) trait RequestEncoder {
type Proto: prost::Message + Default + PartialEq + std::fmt::Debug;
const MSG_ID: OutgoingMessages;
fn to_proto(&self) -> Self::Proto;
fn encode_proto(&self) -> Vec<u8> {
self.to_proto().encode_to_vec()
}
fn encode_request(&self) -> Vec<u8> {
encode_protobuf_message(Self::MSG_ID as i32, &self.encode_proto())
}
}
pub(crate) trait ResponseProtoEncoder {
type Proto: prost::Message;
fn to_proto(&self) -> Self::Proto;
fn encode_proto(&self) -> Vec<u8> {
self.to_proto().encode_to_vec()
}
}
macro_rules! single_req_id_request_builder {
($builder:ident, $proto_type:ident, $msg_id:expr) => {
#[derive(Clone, Copy, Debug)]
pub struct $builder {
pub request_id: i32,
}
impl Default for $builder {
fn default() -> Self {
Self {
request_id: $crate::common::test_utils::helpers::constants::TEST_TICKER_ID,
}
}
}
impl $builder {
pub fn request_id(mut self, v: i32) -> Self {
self.request_id = v;
self
}
}
impl $crate::testdata::builders::RequestEncoder for $builder {
type Proto = $crate::proto::$proto_type;
const MSG_ID: $crate::messages::OutgoingMessages = $msg_id;
fn to_proto(&self) -> Self::Proto {
$crate::proto::$proto_type {
req_id: Some(self.request_id),
}
}
}
};
}
macro_rules! request_id_response_builder {
($builder:ident, $msg_tag:literal, $proto_type:ident) => {
#[derive(Clone, Debug)]
pub struct $builder {
pub request_id: i32,
}
impl Default for $builder {
fn default() -> Self {
Self {
request_id: $crate::common::test_utils::helpers::constants::TEST_TICKER_ID,
}
}
}
impl $builder {
pub fn request_id(mut self, v: i32) -> Self {
self.request_id = v;
self
}
}
impl $crate::testdata::builders::ResponseEncoder for $builder {
fn fields(&self) -> Vec<String> {
vec![$msg_tag.to_string(), "1".to_string(), self.request_id.to_string()]
}
}
impl $crate::testdata::builders::ResponseProtoEncoder for $builder {
type Proto = $crate::proto::$proto_type;
fn to_proto(&self) -> Self::Proto {
$crate::proto::$proto_type {
req_id: Some(self.request_id),
}
}
}
};
}
macro_rules! empty_request_builder {
($builder:ident, $proto_type:ident, $msg_id:expr) => {
#[derive(Clone, Copy, Debug, Default)]
pub struct $builder;
impl $crate::testdata::builders::RequestEncoder for $builder {
type Proto = $crate::proto::$proto_type;
const MSG_ID: $crate::messages::OutgoingMessages = $msg_id;
fn to_proto(&self) -> Self::Proto {
$crate::proto::$proto_type {}
}
}
};
}
fn join_fields(fields: &[String], sep: char) -> String {
let mut out = fields.join(&sep.to_string());
out.push(sep);
out
}
#[allow(dead_code)] pub(crate) fn response_messages(builders: &[&dyn ResponseEncoder]) -> Vec<String> {
builders.iter().map(|b| b.encode_pipe()).collect()
}
#[allow(dead_code)] pub(crate) mod accounts;
#[allow(dead_code)] pub(crate) mod contracts;
#[allow(dead_code)] pub(crate) mod display_groups;
#[allow(dead_code)] pub(crate) mod fundamental;
#[allow(dead_code)] pub(crate) mod market_data;
#[allow(dead_code)] pub(crate) mod news;
#[allow(dead_code)] pub(crate) mod orders;
#[allow(dead_code)] pub(crate) mod positions;
#[allow(dead_code)] pub(crate) mod scanner;
#[allow(dead_code)] pub(crate) mod wsh;
#[cfg(test)]
#[path = "tests.rs"]
mod tests;