Add #![deny(clippy::unwrap_used, clippy::expect_used)] to database, ml-data,
trading-data, and broker_gateway_service crates, fixing all violations:
- database/src/transaction.rs: replace 7x .expect("Transaction already consumed")
with .ok_or_else(|| DatabaseError::Transaction) and 2x .unwrap() on take()
in commit/rollback with safe .ok_or_else() variants
- ml-data/src/performance.rs: replace .last().unwrap() and .first().unwrap()
with if-let destructuring pattern
- trading-data/src/positions.rs: replace 3x write!().unwrap() with let _ = write!()
and Decimal::from_str_exact("0.02").unwrap() with Decimal::new(2, 2)
- trading-data/src/executions.rs: replace 3x write!().unwrap() with let _ = write!(),
and 3x .expect() on and_hms_opt(0,0,0) with .unwrap_or_default()
- broker_gateway_service/src/main.rs: replace encode().unwrap() with if-let,
and from_utf8().unwrap() with .unwrap_or_else()
- Add #[allow(clippy::unwrap_used)] to test modules in all affected crates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
106 lines
3.2 KiB
Rust
106 lines
3.2 KiB
Rust
//! Trading Data Repository
|
|
//!
|
|
//! This crate provides repository pattern implementations for trading data persistence
|
|
//! in high-frequency trading systems. It includes repositories for orders, positions,
|
|
//! and executions with `PostgreSQL` backing.
|
|
//!
|
|
//! # Features
|
|
//!
|
|
//! - Clean repository pattern with trait-based interfaces
|
|
//! - Type-safe database operations with `SQLx`
|
|
//! - Comprehensive error handling
|
|
//! - Async/await support for high-performance operations
|
|
//! - Production-ready patterns for HFT systems
|
|
//!
|
|
//! # Architecture
|
|
//!
|
|
//! The crate follows the repository pattern with trait definitions and `PostgreSQL`
|
|
//! implementations. Each domain entity (Order, Position, Execution) has its own
|
|
//! repository with both basic CRUD operations and domain-specific queries.
|
|
//!
|
|
//! # Usage
|
|
//!
|
|
//! ```rust,no_run
|
|
//! use trading_data::{PostgresOrderRepository, OrderRepository};
|
|
//! use sqlx::postgres::PgPool;
|
|
//!
|
|
//! # async fn example(pool: PgPool) -> Result<(), Box<dyn std::error::Error>> {
|
|
//! let order_repo = PostgresOrderRepository::new(pool);
|
|
//! let orders = order_repo.find_active_orders().await?;
|
|
//! # Ok(())
|
|
//! # }
|
|
//! ```
|
|
|
|
#![deny(missing_docs)]
|
|
#![deny(clippy::unwrap_used, clippy::expect_used)]
|
|
#![warn(clippy::all)]
|
|
#![warn(clippy::pedantic)]
|
|
#![allow(clippy::module_name_repetitions)]
|
|
|
|
pub mod executions;
|
|
pub mod models;
|
|
pub mod orders;
|
|
pub mod positions;
|
|
|
|
// Re-export repository types for public API
|
|
pub use executions::{ExecutionRepository, PostgresExecutionRepository};
|
|
pub use orders::{OrderRepository, PostgresOrderRepository};
|
|
pub use positions::{PositionRepository, PostgresPositionRepository};
|
|
|
|
/// Result type alias for repository operations
|
|
pub type Result<T> = std::result::Result<T, RepositoryError>;
|
|
|
|
/// Common error types for repository operations
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum RepositoryError {
|
|
/// Database operation failed (wraps `SQLx` errors)
|
|
#[error("Database error: {0}")]
|
|
Database(#[from] sqlx::Error),
|
|
|
|
/// Input validation failed
|
|
#[error("Validation error: {0}")]
|
|
Validation(String),
|
|
|
|
/// Requested entity was not found
|
|
#[error("Entity not found: {0}")]
|
|
NotFound(String),
|
|
|
|
/// Operation conflicts with existing state
|
|
#[error("Conflict: {0}")]
|
|
Conflict(String),
|
|
|
|
/// Internal repository error (wraps anyhow errors)
|
|
#[error("Internal error: {0}")]
|
|
Internal(#[from] anyhow::Error),
|
|
}
|
|
|
|
/// Common repository trait for basic CRUD operations
|
|
#[async_trait::async_trait]
|
|
pub trait Repository<T, ID> {
|
|
/// Find entity by ID
|
|
async fn find_by_id(&self, id: &ID) -> Result<Option<T>>;
|
|
|
|
/// Save entity (insert or update)
|
|
async fn save(&self, entity: &T) -> Result<T>;
|
|
|
|
/// Delete entity by ID
|
|
async fn delete(&self, id: &ID) -> Result<bool>;
|
|
|
|
/// Check if entity exists by ID
|
|
async fn exists(&self, id: &ID) -> Result<bool>;
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_error_types() {
|
|
let validation_error = RepositoryError::Validation("test validation".to_string());
|
|
assert!(matches!(validation_error, RepositoryError::Validation(_)));
|
|
|
|
let not_found_error = RepositoryError::NotFound("test entity".to_string());
|
|
assert!(matches!(not_found_error, RepositoryError::NotFound(_)));
|
|
}
|
|
}
|