use std::future::Future;
use std::pin::Pin;
use crate::config::model::{ConsumerConfig, StreamConfig};
use crate::domain::{MarketDataEnvelope, MarketDataType, VenueId};
#[derive(Debug, thiserror::Error)]
pub enum VenueError {
#[error("connection failed for {venue}: {reason}")]
ConnectionFailed { venue: String, reason: String },
#[error("receive failed for {venue}: {reason}")]
ReceiveFailed { venue: String, reason: String },
#[error("subscribe failed for {venue}: {reason}")]
SubscribeFailed { venue: String, reason: String },
#[error("circuit breaker open for {venue}")]
CircuitBreakerOpen { venue: String },
#[error("disconnect failed for {venue}: {reason}")]
DisconnectFailed { venue: String, reason: String },
}
#[derive(Debug, thiserror::Error)]
pub enum NatsError {
#[error("nats connection failed: {0}")]
ConnectionFailed(String),
#[error("publish failed to {subject}: {reason}")]
PublishFailed { subject: String, reason: String },
#[error("stream setup failed for {stream}: {reason}")]
StreamSetupFailed { stream: String, reason: String },
#[error("consumer setup failed for {consumer}: {reason}")]
ConsumerSetupFailed { consumer: String, reason: String },
#[error("nats health check failed: {0}")]
HealthCheckFailed(String),
}
#[derive(Debug, Clone)]
pub struct Subscription {
pub instrument: String,
pub canonical_symbol: String,
pub data_types: Vec<MarketDataType>,
}
#[derive(Debug, Clone)]
pub struct RawMarketData {
pub payload: bytes::Bytes,
pub received_at: u64,
}
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
pub trait VenueAdapter: Send + 'static {
fn venue_id(&self) -> &VenueId;
fn connect(&mut self) -> BoxFuture<'_, Result<(), VenueError>>;
fn subscribe(
&mut self,
subscriptions: &[Subscription],
) -> BoxFuture<'_, Result<(), VenueError>>;
fn next_events(&mut self) -> BoxFuture<'_, Result<Vec<MarketDataEnvelope>, VenueError>>;
fn disconnect(&mut self) -> BoxFuture<'_, Result<(), VenueError>>;
fn is_connected(&self) -> bool;
}
pub trait NatsPublisher: Send + Sync + 'static {
fn publish(
&self,
subject: &str,
payload: &[u8],
content_type: &str,
) -> BoxFuture<'_, Result<(), NatsError>>;
fn ensure_stream(&self, config: &StreamConfig) -> BoxFuture<'_, Result<(), NatsError>>;
fn ensure_consumer(&self, config: &ConsumerConfig) -> BoxFuture<'_, Result<(), NatsError>>;
fn health_check(&self) -> BoxFuture<'_, Result<(), NatsError>>;
}