use super::{Client, ClientBuilder};
use crate::error::{BooruError, Result};
use crate::model::rule34::*;
#[derive(Debug)]
pub struct Rule34Client(ClientBuilder<Self>);
impl From<ClientBuilder<Self>> for Rule34Client {
fn from(value: ClientBuilder<Self>) -> Self {
Self(value)
}
}
impl Client for Rule34Client {
type Post = Rule34Post;
type Rating = Rule34Rating;
const URL: &'static str = "https://api.rule34.xxx";
const SORT: &'static str = "sort:";
const MAX_TAGS: Option<usize> = None;
async fn get_by_id(&self, id: u32) -> Result<Self::Post> {
let builder = &self.0;
let url = &builder.url;
let mut query = vec![
("page", "dapi".to_string()),
("s", "post".to_string()),
("q", "index".to_string()),
("id", id.to_string()),
("json", "1".to_string()),
];
if let (Some(key), Some(user)) = (&builder.key, &builder.user) {
query.push(("api_key", key.clone()));
query.push(("user_id", user.clone()));
}
let response = builder
.client
.get(format!("{url}/index.php"))
.query(&query)
.send()
.await?;
if response.status() == reqwest::StatusCode::UNAUTHORIZED {
return Err(BooruError::Unauthorized(
"Rule34 requires API credentials. Use set_credentials(api_key, user_id)".into(),
));
}
let text = response.text().await?;
if text.contains("Missing authentication") {
return Err(BooruError::Unauthorized(
"Rule34 requires API credentials. Use set_credentials(api_key, user_id)".into(),
));
}
let posts: Vec<Rule34Post> = serde_json::from_str(&text)?;
posts.into_iter().next().ok_or(BooruError::PostNotFound(id))
}
async fn get(&self) -> Result<Vec<Self::Post>> {
let builder = &self.0;
let url = &builder.url;
let tag_string = builder.tags.join(" ");
let mut query = vec![
("page", "dapi".to_string()),
("s", "post".to_string()),
("q", "index".to_string()),
("pid", builder.page.to_string()),
("limit", builder.limit.to_string()),
("tags", tag_string),
("json", "1".to_string()),
];
if let (Some(key), Some(user)) = (&builder.key, &builder.user) {
query.push(("api_key", key.clone()));
query.push(("user_id", user.clone()));
}
let response = builder
.client
.get(format!("{url}/index.php"))
.query(&query)
.send()
.await?;
if response.status() == reqwest::StatusCode::UNAUTHORIZED {
return Err(BooruError::Unauthorized(
"Rule34 requires API credentials. Use set_credentials(api_key, user_id)".into(),
));
}
let text = response.text().await?;
if text.contains("Missing authentication") {
return Err(BooruError::Unauthorized(
"Rule34 requires API credentials. Use set_credentials(api_key, user_id)".into(),
));
}
if text.is_empty() || text == "[]" {
return Ok(Vec::new());
}
let posts: Vec<Rule34Post> = serde_json::from_str(&text)?;
Ok(posts)
}
}