use core::fmt;
#[derive(Clone)]
pub struct Flags {
flags: u16,
}
impl Flags {
const BASIC: u16 = 0b000_000_000_000_01;
const DETAILS: u16 = 0b000_000_000_000_10;
const ANIME: u16 = 0b000_000_000_001_00;
const RELATIONS: u16 = 0b000_000_000_010_00;
const TAGS: u16 = 0b000_000_000_100_00;
const STATS: u16 = 0b000_000_001_000_00;
const SCREENS: u16 = 0b000_000_010_000_00;
const STAFF: u16 = 0b000_000_100_000_00;
const VN: u16 = 0b000_001_000_000_00;
const PRODUCERS: u16 = 0b000_010_000_000_00;
const MEAS: u16 = 0b000_100_000_000_00;
const TRAITS: u16 = 0b001_000_000_000_00;
const VNS: u16 = 0b010_000_000_000_00;
const VOICED: u16 = 0b100_000_000_000_00;
pub fn new() -> Self {
Self {
flags: 0,
}
}
#[inline(always)]
fn push(mut self, flag: u16) -> Self {
self.flags = self.flags | flag;
self
}
pub fn basic(self) -> Self { self.push(Self::BASIC) }
pub fn details(self) -> Self { self.push(Self::DETAILS) }
pub fn anime(self) -> Self { self.push(Self::ANIME) }
pub fn relations(self) -> Self { self.push(Self::RELATIONS) }
pub fn tags(self) -> Self { self.push(Self::TAGS) }
pub fn stats(self) -> Self { self.push(Self::STATS) }
pub fn screens(self) -> Self { self.push(Self::SCREENS) }
pub fn staff(self) -> Self { self.push(Self::STAFF) }
pub fn vn(self) -> Self { self.push(Self::VN) }
pub fn producers(self) -> Self { self.push(Self::PRODUCERS) }
pub fn meas(self) -> Self { self.push(Self::MEAS) }
pub fn traits(self) -> Self { self.push(Self::TRAITS) }
pub fn vns(self) -> Self { self.push(Self::VNS) }
pub fn voiced(self) -> Self { self.push(Self::VOICED) }
}
impl fmt::Display for Flags {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut has_prev = false;
const FLAGS: [(u16, &'static str); 14] = [
(Flags::BASIC, "basic"),
(Flags::DETAILS, "details"),
(Flags::ANIME, "anime"),
(Flags::RELATIONS, "relations"),
(Flags::TAGS, "tags"),
(Flags::STATS, "stats"),
(Flags::SCREENS, "screens"),
(Flags::STAFF, "staff"),
(Flags::VN, "vn"),
(Flags::PRODUCERS, "producers"),
(Flags::MEAS, "meas"),
(Flags::TRAITS, "traits"),
(Flags::VNS, "vns"),
(Flags::VOICED, "voiced"),
];
for (flag, name) in FLAGS.iter() {
if self.flags & flag > 0 {
if has_prev {
write!(f, ",")?;
}
has_prev = true;
write!(f, "{}", name)?;
}
}
Ok(())
}
}
#[derive(Clone)]
pub struct Type {
inner: &'static str
}
impl Type {
pub const fn vn() -> Self { Self { inner: "vn" } }
pub const fn release() -> Self { Self { inner: "release" } }
pub const fn producer() -> Self { Self { inner: "producer" } }
pub const fn character() -> Self { Self { inner: "character" } }
pub const fn staff() -> Self { Self { inner: "staff" } }
pub const fn user() -> Self { Self { inner: "user" } }
pub const fn votelist() -> Self { Self { inner: "votelist" } }
pub const fn vnlist() -> Self { Self { inner: "vnlist" } }
pub const fn wishlist() -> Self { Self { inner: "wishlist" } }
pub const fn ulist() -> Self { Self { inner: "ulist" } }
pub fn short(&self) -> &str {
&self.inner[..1]
}
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.inner)
}
}
#[macro_export]
macro_rules! filter {
($left:tt $op:tt $var:ident) => {
format_args!("{} {} {}", stringify!($left), stringify!($op), $var)
};
($left:tt $op:tt $var:tt) => {
format_args!("{} {} {}", stringify!($left), stringify!($op), stringify!($var))
}
}
#[derive(Clone)]
pub struct Filters {
inner: Vec<String>
}
impl Filters {
pub fn new() -> Self {
Self {
inner: vec![]
}
}
pub fn filter<T: fmt::Display>(mut self, element: T) -> Self {
self.inner.push(format!("{}", element));
self
}
pub fn and<T: fmt::Display>(self, filter: T) -> Self {
self.filter("and").filter(filter)
}
pub fn or<T: fmt::Display>(self, filter: T) -> Self {
self.filter("or").filter(filter)
}
}
impl fmt::Display for Filters {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.inner.len() {
0 => Ok(()),
len => {
let last_element = len - 1;
write!(f, "(")?;
for idx in 0..last_element {
write!(f, "{} ", unsafe { self.inner.get_unchecked(idx) })?;
}
write!(f, "{})", unsafe { self.inner.get_unchecked(last_element) })
}
}
}
}
#[derive(Debug, Clone)]
pub struct Options<'a> {
pub page: Option<u32>,
pub results: Option<u32>,
pub sort: Option<&'a str>,
pub reverse: Option<bool>
}
impl<'a> fmt::Display for Options<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{{")?;
let mut has_prev = false;
if let Some(page) = self.page {
has_prev = true;
write!(f, "\"page\":{}", page)?;
}
if let Some(results) = self.results {
if has_prev {
write!(f, ",")?;
}
has_prev = true;
write!(f, "\"results\":{}", results)?;
}
if let Some(ref sort) = self.sort {
if has_prev {
write!(f, ",")?;
}
has_prev = true;
write!(f, "\"sort\":{}", sort)?;
}
if let Some(ref reverse) = self.reverse {
if has_prev {
write!(f, ",")?;
}
write!(f, "\"reverse\":{}", reverse)?;
}
write!(f, "}}")
}
}