pub use thiserror::Error;
use convert::Argument;
use std::fmt::Formatter;
mod convert;
#[derive(Debug, Error, Copy, Clone)]
pub enum LoliError {
IllegalNum,
IllegalSize,
IllegalUidLen,
IllegalTags,
}
impl std::fmt::Display for LoliError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{:?}", self)?;
Ok(())
}
}
#[derive(Clone, Debug)]
pub struct Request {
r18: Option<R18>,
num: Option<u8>,
uid: Option<Vec<u32>>,
keyword: Keyword,
tag: Tag,
size: Size,
proxy: Proxy,
date_after: DateAfter,
date_before: DateBefore,
dsc: Option<bool>,
}
impl std::default::Default for Request {
fn default() -> Self {
Request {
r18: None, num: None, uid: None,
keyword: Keyword(None),
tag: Tag(None),
size: Size(None), proxy: Proxy(None), date_after: DateAfter(None),
date_before: DateBefore(None),
dsc: None, }
}
}
impl Request {
pub fn r18(mut self, r: R18) -> Self {
self.r18 = Some(r);
self
}
pub fn num(mut self, amount: u8) -> Result<Self, LoliError> {
match amount {
1..=100 => {
self.num = Some(amount);
Ok(self)
}
_ => Err(LoliError::IllegalNum),
}
}
pub fn uid(mut self, authors: Vec<u32>) -> Result<Self, LoliError> {
match authors.len() {
1..=20 => {
self.uid = Some(authors);
Ok(self)
}
_ => Err(LoliError::IllegalUidLen),
}
}
pub fn keyword(mut self, keyword: impl Into<String>) -> Self {
self.keyword.0 = Some(keyword.into());
self
}
pub fn tag(mut self, tag: Vec<String>) -> Result<Self, LoliError> {
match tag.len() {
1..=20 => {
self.tag.0 = Some(tag);
Ok(self)
}
_ => Err(LoliError::IllegalTags),
}
}
pub fn size(mut self, size_list: Vec<ImageSize>) -> Result<Self, LoliError> {
match size_list.len() {
1..=5 => {
self.size.0 = Some(size_list);
Ok(self)
}
_ => Err(LoliError::IllegalSize),
}
}
pub fn proxy(mut self, proxy: impl Into<String>) -> Self {
self.proxy.0 = Some(proxy.into());
self
}
pub fn date_after(mut self, date_after: u64) -> Self {
self.date_after.0 = Some(date_after);
self
}
pub fn date_before(mut self, date_before: u64) -> Self {
self.date_before.0 = Some(date_before);
self
}
pub fn dsc(mut self, dsc: bool) -> Self {
self.dsc = Some(dsc);
self
}
}
#[derive(Copy, Clone, Debug)]
pub enum R18 {
NonR18,
R18,
Mixin,
}
#[derive(Debug, Clone)]
pub struct Keyword(Option<String>);
#[derive(Debug, Clone)]
pub struct Tag(Option<Vec<String>>);
#[derive(Debug, Clone)]
pub struct Size(Option<Vec<ImageSize>>);
#[derive(Debug, Clone)]
pub enum ImageSize {
Original,
Regular,
Small,
Thumb,
Mini,
}
#[derive(Debug, Clone)]
pub struct Proxy(Option<String>);
#[derive(Debug, Clone)]
pub struct DateAfter(Option<u64>);
#[derive(Debug, Clone)]
pub struct DateBefore(Option<u64>);
impl std::fmt::Display for ImageSize {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let parameter = match self {
ImageSize::Original => "original",
ImageSize::Regular => "regular",
ImageSize::Small => "small",
ImageSize::Thumb => "thumb",
ImageSize::Mini => "mini",
};
write!(f, "{}", parameter)
}
}
impl From<Request> for String {
fn from(req: Request) -> Self {
let mut url: String = "https://api.lolicon.app/setu/v2?".into();
url.add_argument(req.r18);
url.add_argument(req.num);
url.add_argument(req.uid);
url.add_argument(req.keyword);
url.add_argument(req.tag);
url.add_argument(req.size);
url.add_argument(req.proxy);
url.add_argument(req.date_after);
url.add_argument(req.date_before);
url.add_argument(req.dsc);
url
}
}
trait AddArgument {
fn add_argument(&mut self, object: impl Argument);
}
impl AddArgument for String {
fn add_argument(&mut self, object: impl Argument) {
object.argument(self);
}
}