use crate::models::{ListingData, RedditResponse, RedditResponseGeneric};
use crate::items::{
search::{PostSearch, SubredditSearch, UserSearch},
submission::Submission,
subreddit::SubredditLink,
user::RedditUserLink,
AbstractedApi,
};
use crate::endpoints::{self, Endpoint, EndpointBase, EndpointBuilder, SearchSort};
use crate::rate_limit::RateLimiter;
use crate::reddit_app::RedditApp;
use serde::de::DeserializeOwned;
use std::io;
#[derive(Clone)]
pub struct Reddit {
pub(crate) app: RedditApp,
}
impl Reddit {
pub fn new() -> io::Result<Reddit> {
Ok(Reddit {
app: RedditApp::new()?,
})
}
pub fn from_app(app: RedditApp) -> io::Result<Reddit> {
Ok(Reddit { app: app })
}
pub fn bind<'r, T: AbstractedApi<'r>>(&'r self, api_data: T::ApiType) -> T::AbstractedType {
T::from_parent(self, api_data)
}
pub fn ep(&self, builder: EndpointBuilder) -> io::Result<Endpoint> {
self.app.create_endpoint(builder)
}
pub fn ep_str(&self, str_ep: &str) -> io::Result<Endpoint> {
self.app.create_enddpoint_str(str_ep)
}
pub(crate) async fn get_data<T: DeserializeOwned>(
&self,
ep: Endpoint,
) -> io::Result<RedditResponseGeneric<T>> {
self.app
.create_request::<RedditResponseGeneric<T>>(ep.to_url())
.await
}
pub(crate) async fn get_list<T: DeserializeOwned>(&self, ep: Endpoint) -> io::Result<Vec<T>> {
let data = self.get_data::<ListingData<T>>(ep).await?;
let infos = data.data.inner_children();
Ok(infos)
}
pub fn rate_limit_off(mut self) -> Self {
self.app.rate_limiter = RateLimiter::Off;
self
}
pub fn rate_limit_bacthed(mut self) -> Self {
self.app.rate_limiter = RateLimiter::new_batched();
self
}
pub fn rate_limit_paced(mut self) -> Self {
self.app.rate_limiter = RateLimiter::new_paced();
self
}
pub fn user(&self, username: &str) -> RedditUserLink {
RedditUserLink::new(self, username)
}
pub fn subreddit(&self, name: &str) -> SubredditLink {
SubredditLink::new(self, name)
}
pub async fn search<'r, 's>(
&'r self,
query: &'s str,
sort: SearchSort,
) -> io::Result<PostSearch<'r, 's>> {
let search_ep = self.ep(endpoints::SEARCH)?;
PostSearch::new_search(self, search_ep, query, sort).await
}
pub async fn search_subreddits<'r, 's>(
&'r self,
query: &'s str,
sort: SearchSort,
) -> io::Result<SubredditSearch<'r, 's>> {
let search_ep = self.ep(endpoints::SUBREDDITS_SEARCH)?;
SubredditSearch::new_search(self, search_ep, query, sort).await
}
pub async fn search_users<'r, 's>(
&'r self,
query: &'s str,
sort: SearchSort,
) -> io::Result<UserSearch<'r, 's>> {
let search_ep = self.ep(endpoints::USERS_SEARCH)?;
UserSearch::new_search(self, search_ep, query, sort).await
}
pub async fn submission_from_link(&self, url: &'_ str) -> io::Result<Submission<'_>> {
let page_link = self.ep_str(url)?;
let post_data = self
.get_data::<ListingData<RedditResponse>>(page_link)
.await?;
Ok(Submission::from_resp(self, post_data.data))
}
}