Skip to main content

finlight_client/
services.rs

1use std::sync::Arc;
2
3use serde::Deserialize;
4
5use crate::error::Error;
6use crate::http::ApiClient;
7use crate::models::{Article, ArticleResponse, Source};
8use crate::params::{GetArticleByLinkParams, GetArticlesParams};
9
10/// Fetches financial news articles.
11#[derive(Clone)]
12pub struct ArticleService {
13    pub(crate) api: Arc<ApiClient>,
14}
15
16impl ArticleService {
17    /// Searches articles matching `params` and returns one result page.
18    pub async fn fetch_articles(
19        &self,
20        params: &GetArticlesParams,
21    ) -> Result<ArticleResponse, Error> {
22        self.api.post("/v2/articles", params).await
23    }
24
25    /// Fetches a single article by its URL.
26    pub async fn fetch_article_by_link(
27        &self,
28        params: &GetArticleByLinkParams,
29    ) -> Result<Article, Error> {
30        #[derive(Deserialize)]
31        struct Envelope {
32            article: Article,
33        }
34
35        let mut query = vec![("link", params.link.clone())];
36        if params.include_content {
37            query.push(("includeContent", "true".to_owned()));
38        }
39        if params.include_entities {
40            query.push(("includeEntities", "true".to_owned()));
41        }
42        let envelope: Envelope = self.api.get("/v2/articles/by-link", &query).await?;
43        Ok(envelope.article)
44    }
45}
46
47/// Lists the news sources available through the API.
48#[derive(Clone)]
49pub struct SourceService {
50    pub(crate) api: Arc<ApiClient>,
51}
52
53impl SourceService {
54    /// Returns all sources with their availability flags.
55    pub async fn get_sources(&self) -> Result<Vec<Source>, Error> {
56        self.api.get("/v2/sources", &[]).await
57    }
58}