use crate::{
client::FinnhubClient,
error::Result,
models::stock::{CompanyProfile, Symbol},
};
pub struct CompanyEndpoints<'a> {
client: &'a FinnhubClient,
}
impl<'a> CompanyEndpoints<'a> {
pub fn new(client: &'a FinnhubClient) -> Self {
Self { client }
}
pub async fn profile(&self, symbol: &str) -> Result<CompanyProfile> {
self.client
.get(&format!("/stock/profile2?symbol={}", symbol))
.await
}
pub async fn peers(&self, symbol: &str, grouping: Option<&str>) -> Result<Vec<String>> {
let url = if let Some(grouping) = grouping {
format!("/stock/peers?symbol={}&grouping={}", symbol, grouping)
} else {
format!("/stock/peers?symbol={}", symbol)
};
self.client.get(&url).await
}
pub async fn symbols(&self, exchange: &str) -> Result<Vec<Symbol>> {
self.client
.get(&format!("/stock/symbol?exchange={}", exchange))
.await
}
}
#[cfg(test)]
mod tests {
use crate::{ClientConfig, FinnhubClient, RateLimitStrategy};
async fn test_client() -> FinnhubClient {
dotenv::dotenv().ok();
let api_key = std::env::var("FINNHUB_API_KEY").unwrap_or_else(|_| "test_key".to_string());
let mut config = ClientConfig::default();
config.rate_limit_strategy = RateLimitStrategy::FifteenSecondWindow;
FinnhubClient::with_config(api_key, config)
}
#[tokio::test]
#[ignore = "requires API key"]
async fn test_company_profile() {
let client = test_client().await;
let result = client.stock().company_profile("AAPL").await;
assert!(
result.is_ok(),
"Failed to get company profile: {:?}",
result.err()
);
let profile = result.unwrap();
assert!(profile.name.is_some());
assert_eq!(profile.ticker.as_deref(), Some("AAPL"));
}
#[tokio::test]
#[ignore = "requires API key"]
async fn test_peers() {
let client = test_client().await;
let result = client.stock().peers("AAPL", None).await;
assert!(result.is_ok(), "Failed to get peers: {:?}", result.err());
let peers = result.unwrap();
assert!(!peers.is_empty());
assert!(peers.len() <= 10); }
#[tokio::test]
#[ignore = "requires API key"]
async fn test_symbols() {
let client = test_client().await;
let result = client.stock().symbols("US").await;
assert!(result.is_ok(), "Failed to get symbols: {:?}", result.err());
let symbols = result.unwrap();
assert!(!symbols.is_empty());
if let Some(symbol) = symbols.first() {
assert!(!symbol.symbol.is_empty());
assert!(!symbol.description.is_empty());
}
}
}