finnhub 0.2.0

A comprehensive Rust client for the Finnhub.io financial data API with 96% endpoint coverage, flexible rate limiting, and WebSocket support
Documentation
# Contributing to finnhub

Thank you for your interest in contributing to finnhub! This document provides guidelines and instructions for contributing.

## Code of Conduct

By participating in this project, you agree to abide by our code of conduct: be respectful, inclusive, and constructive.

## How to Contribute

### Reporting Bugs

Before creating bug reports, please check existing issues to avoid duplicates. When creating a bug report, include:

- A clear and descriptive title
- Steps to reproduce the issue
- Expected behavior vs actual behavior
- Your environment (OS, Rust version, finnhub-rs version)
- Any relevant code snippets or error messages

### Suggesting Enhancements

Enhancement suggestions are welcome! Please provide:

- A clear and descriptive title
- Detailed description of the proposed feature
- Use cases and benefits
- Any relevant examples from other libraries

### Pull Requests

1. Fork the repository and create your branch from `develop`
2. If you've added code, add tests that cover your changes
3. Ensure all tests pass: `cargo test`
4. Make sure your code follows the style guidelines: `cargo fmt`
5. Ensure there are no clippy warnings: `cargo clippy -- -D warnings`
6. Update documentation for any API changes
7. Add an entry to CHANGELOG.md if appropriate

## Development Setup

```bash
# Clone your fork
git clone https://github.com/yourusername/finnhub
cd finnhub

# Add upstream remote
git remote add upstream https://github.com/jbradenbrown/finnhub

# Create a feature branch
git checkout -b feature/your-feature-name

# Install development dependencies
cargo build

# Run tests (requires API key)
FINNHUB_API_KEY=your_key cargo test

# Run a specific test
FINNHUB_API_KEY=your_key cargo test test_name

# Run examples
FINNHUB_API_KEY=your_key cargo run --example basic_usage
```

## Style Guidelines

### Rust Code Style

- Follow standard Rust naming conventions
- Use `cargo fmt` to format code
- Use `cargo clippy` to catch common mistakes
- Prefer explicit types for public APIs
- Add documentation comments for all public items
- Use `#[must_use]` where appropriate

### Commit Messages

Follow the conventional commits specification:

```
type(scope): subject

body

footer
```

Types:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code style changes (formatting, etc.)
- `refactor`: Code refactoring
- `test`: Adding or updating tests
- `chore`: Maintenance tasks

Example:
```
feat(stock): add insider sentiment endpoint

- Add insider_sentiment() method to StockEndpoints
- Add InsiderSentimentData model
- Update documentation and examples
```

### Documentation

- All public APIs must have documentation comments
- Include examples in doc comments where helpful
- Update README.md for significant features
- Keep CLAUDE.md updated with architectural decisions

### Testing

- Write unit tests for model serialization/deserialization
- Write integration tests for new endpoints (using mocks when possible)
- Test error conditions, not just happy paths
- Use descriptive test names that explain what is being tested

Example test:
```rust
#[tokio::test]
async fn test_stock_quote_handles_invalid_symbol() {
    let client = FinnhubClient::new("test_key");
    let result = client.stock().quote("INVALID123").await;
    
    assert!(result.is_err());
    match result.unwrap_err() {
        Error::NotFound => {}
        e => panic!("Expected NotFound error, got: {:?}", e),
    }
}
```

## Project Structure

```
finnhub/
├── src/
│   ├── client.rs           # Main client implementation
│   ├── endpoints/          # API endpoint implementations
│   │   ├── stock/          # Stock endpoints (14 modules)
│   │   └── ...             # Other endpoint categories
│   ├── models/             # Response/request models
│   │   ├── stock/          # Stock models (14 files)
│   │   └── ...             # Other model categories
│   ├── error.rs            # Error types
│   ├── auth.rs             # Authentication
│   └── rate_limiter.rs     # Rate limiting
├── examples/               # Usage examples
├── tests/                  # Integration tests
└── benches/               # Performance benchmarks
```

## Adding New Endpoints

1. Check the [Finnhub API documentation]https://finnhub.io/docs/api
2. Add the endpoint method to the appropriate file in `src/endpoints/`
3. Create request/response models in `src/models/`
4. Add tests for the new endpoint
5. Update the API coverage in README.md and CLAUDE.md
6. Add an example if the endpoint introduces new concepts

Example:
```rust
// In src/endpoints/stock.rs
impl<'a> StockEndpoints<'a> {
    /// Get company ESG scores.
    pub async fn esg(&self, symbol: &str) -> Result<ESGScore> {
        self.client
            .get(&format!("/stock/esg?symbol={}", symbol))
            .await
    }
}

// In src/models/stock/compliance.rs
/// ESG (Environmental, Social, Governance) scores.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ESGScore {
    /// Symbol
    pub symbol: String,
    /// ESG scores
    pub esg_scores: Vec<ESGData>,
}
```

## Development Tools

This project was initially developed using [Claude Code](https://github.com/anthropics/claude-code), and we welcome contributions made with AI assistance. If you use AI tools in your contributions:

1. Ensure you understand and can explain all code you submit
2. Test thoroughly - AI-generated code may have subtle issues
3. Follow all the same quality standards as human-written code
4. Consider mentioning AI assistance in your PR for transparency

## Questions?

Feel free to open an issue for any questions about contributing. We're here to help!