1pub mod error;
2pub mod portal;
3
4pub use self::error::FeedApiError;
5pub use self::portal::Portal;
6use crate::models::{
7 ApiSecret, ArticleID, Category, CategoryID, FavIcon, Feed, FeedID, FeedUpdateResult, LoginData, Marked, PluginCapabilities, PluginID, PluginInfo,
8 Read, SyncResult, TagID, Url,
9};
10use async_trait::async_trait;
11use reqwest::Client;
12use reqwest::header::{HeaderMap, HeaderValue};
13use std::collections::HashMap;
14use std::path::Path;
15
16#[cfg(test)]
17use mockall::{automock, predicate::*};
18
19pub type FeedApiResult<T> = Result<T, FeedApiError>;
20pub type FeedHeaderMap = HashMap<FeedID, HeaderMap<HeaderValue>>;
21
22pub trait ApiMetadata {
23 fn id(&self) -> PluginID;
24 fn info(&self) -> FeedApiResult<PluginInfo>;
25 fn get_instance(&self, config_dir: &Path, portal: Box<dyn Portal>, user_api_secret: Option<ApiSecret>) -> FeedApiResult<Box<dyn FeedApi>>;
26}
27
28#[cfg_attr(test, automock)]
29#[async_trait]
30pub trait FeedApi: Send + Sync {
31 fn features(&self) -> FeedApiResult<PluginCapabilities>;
32 fn has_user_configured(&self) -> FeedApiResult<bool>;
33 async fn user_name(&self) -> Option<String>;
34 async fn get_login_data(&self) -> Option<LoginData>;
35 async fn is_reachable(&self, client: &Client) -> FeedApiResult<bool>;
36 async fn is_logged_in(&self, client: &Client) -> FeedApiResult<bool>;
37 async fn login(&mut self, data: LoginData, client: &Client) -> FeedApiResult<()>;
38 async fn logout(&mut self, client: &Client) -> FeedApiResult<()>;
39 async fn initial_sync(&self, client: &Client, custom_header: FeedHeaderMap) -> FeedApiResult<SyncResult>;
40 async fn sync(&self, client: &Client, custom_header: FeedHeaderMap) -> FeedApiResult<SyncResult>;
41 async fn fetch_feed(&self, feed_id: &FeedID, client: &Client, custom_header: HeaderMap<HeaderValue>) -> FeedApiResult<FeedUpdateResult>;
42 async fn set_article_read(&self, articles: &[ArticleID], read: Read, client: &Client) -> FeedApiResult<()>;
43 async fn set_article_marked(&self, articles: &[ArticleID], marked: Marked, client: &Client) -> FeedApiResult<()>;
44 async fn set_feed_read(&self, feeds: &[FeedID], articles: &[ArticleID], client: &Client) -> FeedApiResult<()>;
45 async fn set_category_read(&self, categories: &[CategoryID], articles: &[ArticleID], client: &Client) -> FeedApiResult<()>;
46 async fn set_tag_read(&self, tags: &[TagID], articles: &[ArticleID], client: &Client) -> FeedApiResult<()>;
47 async fn set_all_read(&self, articles: &[ArticleID], client: &Client) -> FeedApiResult<()>;
48 async fn add_feed(
49 &self,
50 url: &Url,
51 title: Option<String>,
52 category: Option<CategoryID>,
53 client: &Client,
54 ) -> FeedApiResult<(Feed, Option<Category>)>;
55 async fn remove_feed(&self, id: &FeedID, client: &Client) -> FeedApiResult<()>;
56 async fn move_feed(&self, feed_id: &FeedID, from: &CategoryID, to: &CategoryID, client: &Client) -> FeedApiResult<()>;
57 async fn rename_feed(&self, feed_id: &FeedID, new_title: &str, client: &Client) -> FeedApiResult<FeedID>;
58 async fn edit_feed_url(&self, feed_id: &FeedID, new_url: &str, client: &Client) -> FeedApiResult<()>;
59 async fn add_category<'a>(&self, title: &str, parent: Option<&'a CategoryID>, client: &Client) -> FeedApiResult<CategoryID>;
60 async fn remove_category(&self, id: &CategoryID, remove_children: bool, client: &Client) -> FeedApiResult<()>;
61 async fn rename_category(&self, id: &CategoryID, new_title: &str, client: &Client) -> FeedApiResult<CategoryID>;
62 async fn move_category(&self, id: &CategoryID, parent: &CategoryID, client: &Client) -> FeedApiResult<()>;
63 async fn import_opml(&self, opml: &str, client: &Client) -> FeedApiResult<()>;
64 async fn add_tag(&self, title: &str, client: &Client) -> FeedApiResult<TagID>;
65 async fn remove_tag(&self, id: &TagID, client: &Client) -> FeedApiResult<()>;
66 async fn rename_tag(&self, id: &TagID, new_title: &str, client: &Client) -> FeedApiResult<TagID>;
67 async fn tag_article(&self, article_id: &ArticleID, tag_id: &TagID, client: &Client) -> FeedApiResult<()>;
68 async fn untag_article(&self, article_id: &ArticleID, tag_id: &TagID, client: &Client) -> FeedApiResult<()>;
69 async fn get_favicon(&self, feed_id: &FeedID, client: &Client, custom_header: HeaderMap<HeaderValue>) -> FeedApiResult<FavIcon>;
70}