use crate::resource::ResourceField;
use std::default::Default;
use std::fmt::Write;
use std::marker::PhantomData;
#[derive(Debug)]
pub struct ObjectOption<Field> {
select_buf: String,
expand_buf: String,
_marker: PhantomData<Fn(&Field)>,
}
impl<Field: ResourceField> ObjectOption<Field> {
pub fn new() -> Self {
Self {
select_buf: String::new(),
expand_buf: String::new(),
_marker: PhantomData,
}
}
pub fn select(mut self, fields: &[Field]) -> Self {
for sel in fields {
self = self.select_raw(&[sel.api_field_name()]);
}
self
}
fn select_raw(mut self, fields: &[&str]) -> Self {
for sel in fields {
write!(self.select_buf, ",{}", sel).unwrap();
}
self
}
pub fn expand(self, field: Field, select_children: Option<&[&str]>) -> Self {
self.expand_raw(field.api_field_name(), select_children)
}
fn expand_raw(mut self, field: &str, select_children: Option<&[&str]>) -> Self {
let buf = &mut self.expand_buf;
write!(buf, ",{}", field).unwrap();
if let Some(children) = select_children {
write!(buf, "($select=").unwrap();
for sel in children {
write!(buf, "{},", sel).unwrap();
}
write!(buf, ")").unwrap();
}
self
}
pub(crate) fn params(&self) -> impl Iterator<Item = (&str, &str)> {
std::iter::empty()
.chain(self.select_buf.get(1..).map(|s| ("$select", s)))
.chain(self.expand_buf.get(1..).map(|s| ("$expand", s)))
}
}
impl<Field: ResourceField> Default for ObjectOption<Field> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug)]
pub struct CollectionOption<Field> {
q: ObjectOption<Field>,
order_buf: Option<String>,
page_size_buf: Option<String>,
get_count_buf: Option<bool>,
}
impl<Field: ResourceField> CollectionOption<Field> {
pub fn new() -> Self {
Self {
q: Default::default(),
order_buf: None,
page_size_buf: None,
get_count_buf: None,
}
}
pub fn select(mut self, fields: &[Field]) -> Self {
self.q = self.q.select(fields);
self
}
pub fn expand(mut self, field: Field, select_children: Option<&[&str]>) -> Self {
self.q = self.q.expand(field, select_children);
self
}
pub fn order_by(mut self, field: Field, order: Order) -> Self {
let order = match order {
Order::Ascending => "asc",
Order::Descending => "desc",
};
self.order_buf = Some(format!("{} {}", field.api_field_name(), order));
self
}
pub fn page_size(mut self, size: usize) -> Self {
self.page_size_buf = Some(size.to_string());
self
}
pub fn get_count(mut self, get_count: bool) -> Self {
self.get_count_buf = Some(get_count);
self
}
pub(crate) fn params(&self) -> impl Iterator<Item = (&str, &str)> {
self.q
.params()
.chain(self.order_buf.as_ref().map(|s| ("$orderby", &**s)))
.chain(self.page_size_buf.as_ref().map(|s| ("$top", &**s)))
.chain(
self.get_count_buf
.map(|v| ("$count", if v { "true" } else { "false" })),
)
}
}
impl<Field: ResourceField> Default for CollectionOption<Field> {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum Order {
Ascending,
Descending,
}