use std::borrow::Cow;
use url::Url;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ODataQuery {
select: Option<String>,
expand: Option<String>,
top: Option<u64>,
skip: Option<u64>,
filter: Option<String>,
orderby: Option<String>,
extra: Vec<(String, String)>,
}
impl ODataQuery {
pub fn new() -> Self {
Self::default()
}
pub fn select(mut self, value: impl Into<String>) -> Self {
self.select = Some(value.into());
self
}
pub fn expand(mut self, value: impl Into<String>) -> Self {
self.expand = Some(value.into());
self
}
pub fn top(mut self, value: u64) -> Self {
self.top = Some(value);
self
}
pub fn skip(mut self, value: u64) -> Self {
self.skip = Some(value);
self
}
pub fn filter(mut self, value: impl Into<String>) -> Self {
self.filter = Some(value.into());
self
}
pub fn orderby(mut self, value: impl Into<String>) -> Self {
self.orderby = Some(value.into());
self
}
pub fn with_pair(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.extra.push((key.into(), value.into()));
self
}
pub fn apply_to_url(&self, mut url: Url) -> Url {
{
let mut qp = url.query_pairs_mut();
if let Some(v) = &self.select {
qp.append_pair("$select", v);
}
if let Some(v) = &self.expand {
qp.append_pair("$expand", v);
}
if let Some(v) = self.top {
qp.append_pair("$top", &v.to_string());
}
if let Some(v) = self.skip {
qp.append_pair("$skip", &v.to_string());
}
if let Some(v) = &self.filter {
qp.append_pair("$filter", v);
}
if let Some(v) = &self.orderby {
qp.append_pair("$orderby", v);
}
for (k, v) in &self.extra {
qp.append_pair(k, v);
}
}
url
}
pub fn pairs(&self) -> Vec<(Cow<'static, str>, Cow<'_, str>)> {
let mut out: Vec<(Cow<'static, str>, Cow<'_, str>)> = Vec::new();
if let Some(v) = &self.select {
out.push((Cow::Borrowed("$select"), Cow::Borrowed(v.as_str())));
}
if let Some(v) = &self.expand {
out.push((Cow::Borrowed("$expand"), Cow::Borrowed(v.as_str())));
}
if let Some(v) = self.top {
out.push((Cow::Borrowed("$top"), Cow::Owned(v.to_string())));
}
if let Some(v) = self.skip {
out.push((Cow::Borrowed("$skip"), Cow::Owned(v.to_string())));
}
if let Some(v) = &self.filter {
out.push((Cow::Borrowed("$filter"), Cow::Borrowed(v.as_str())));
}
if let Some(v) = &self.orderby {
out.push((Cow::Borrowed("$orderby"), Cow::Borrowed(v.as_str())));
}
for (k, v) in &self.extra {
out.push((Cow::Owned(k.clone()), Cow::Borrowed(v.as_str())));
}
out
}
}