Thank you for your interest in contributing to CCXT-Rust! This document provides guidelines and information for contributors.
- Code of Conduct
- Getting Started
- Development Setup
- Making Changes
- Adding a New Exchange
- Testing
- Pull Request Process
- Style Guide
By participating in this project, you agree to maintain a respectful and inclusive environment. Please be considerate of others and focus on constructive collaboration.
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/trading.git - Navigate to ccxt-rust:
cd trading/ccxt-rust - Create a new branch:
git checkout -b feature/your-feature-name
- Rust 1.70 or higher
- Cargo (comes with Rust)
# Build with default features (CEX only)
cargo build
# Build with all features
cargo build --features full
# Build in release mode
cargo build --release# Run all tests
cargo test --features full
# Run specific test
cargo test test_name --features full
# Run with output
cargo test --features full -- --nocapture# Run clippy lints
cargo clippy --features full -- -D warnings
# Format code
cargo fmt
# Check formatting
cargo fmt -- --check
# Build documentation
cargo doc --features full --no-depsfeature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test additions or modifications
Follow conventional commits format:
type(scope): description
[optional body]
[optional footer]
Types: feat, fix, docs, style, refactor, test, chore
Examples:
feat(binance): add spot margin trading support
fix(websocket): handle reconnection on network failure
docs(readme): update installation instructions
- CEX: Add to
src/exchanges/cex/ - DEX: Add to
src/exchanges/dex/
// src/exchanges/cex/newexchange.rs
use crate::client::{ExchangeConfig, HttpClient};
use crate::errors::CcxtResult;
use crate::types::*;
use async_trait::async_trait;
pub struct NewExchange {
client: HttpClient,
// ... other fields
}
impl NewExchange {
pub fn new(config: ExchangeConfig) -> CcxtResult<Self> {
// Implementation
}
}
#[async_trait]
impl Exchange for NewExchange {
fn id(&self) -> ExchangeId {
ExchangeId::NewExchange
}
fn name(&self) -> &str {
"New Exchange"
}
// Implement required methods...
}Create src/exchanges/cex/newexchange_ws.rs implementing WsExchange trait.
// src/exchanges/cex/mod.rs
mod newexchange;
pub use newexchange::NewExchange;
// If WebSocket:
mod newexchange_ws;
pub use newexchange_ws::NewExchangeWs;// src/types/exchange.rs
pub enum ExchangeId {
// ...existing exchanges...
NewExchange,
}#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_newexchange_creation() {
let config = ExchangeConfig::new();
let exchange = NewExchange::new(config);
assert!(exchange.is_ok());
}
#[tokio::test]
async fn test_newexchange_features() {
// Test exchange features
}
}Create examples/newexchange_example.rs demonstrating usage.
- Unit Tests: Test individual components
- Integration Tests: Test in
tests/directory - Live API Tests: Test against real APIs (ignored by default)
# CEX live tests
cargo test --features full live_api -- --ignored --test-threads=1
# DEX live tests
cargo test --features full live_dex -- --ignored --test-threads=1- Test both success and error cases
- Use meaningful test names
- Add comments for complex test logic
- Mock external dependencies when possible
- Ensure all tests pass:
cargo test --features full - Run clippy:
cargo clippy --features full -- -D warnings - Format code:
cargo fmt - Update documentation if needed
- Add tests for new functionality
Include:
- Summary of changes
- Related issue number (if applicable)
- Breaking changes (if any)
- Testing performed
- Automated CI checks must pass
- At least one maintainer review required
- Address all review comments
- Squash commits if requested
- Follow Rust API guidelines
- Use
rustfmtfor formatting - Prefer explicit types over inference when it aids readability
- Document public APIs with doc comments
/// Brief description of the function.
///
/// More detailed explanation if needed.
///
/// # Arguments
///
/// * `param` - Description of parameter
///
/// # Returns
///
/// Description of return value
///
/// # Errors
///
/// Description of possible errors
///
/// # Examples
///
/// ```rust
/// let result = function(param);
/// ```
pub fn function(param: Type) -> Result<Type, Error> {
// Implementation
}- Use
CcxtErrorfor exchange-related errors - Provide meaningful error messages
- Include context in error messages
- Use
async_traitfor async trait methods - Prefer
tokioruntime primitives - Handle timeouts and cancellation properly
- Open an issue for bugs or feature requests
- Check existing issues before creating new ones
- Be specific and provide reproduction steps for bugs
Thank you for contributing!