use serde::Serialize;
#[derive(Debug, PartialEq, Clone)]
pub struct Options {
start: Option<String>,
end: Option<String>,
limit: Option<usize>,
status: Option<Status>,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
#[non_exhaustive]
pub enum Status {
#[allow(missing_docs)]
Succeeded,
#[allow(missing_docs)]
Failed,
}
#[derive(Debug, PartialEq, Clone)]
pub struct OptionsBuilder(Options);
#[derive(Serialize)]
pub(crate) struct SerializableOptions<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
start: &'a Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
end: &'a Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
status: Option<&'static str>,
}
impl Options {
pub fn builder() -> OptionsBuilder {
OptionsBuilder::new()
}
pub fn urlencoded(&self) -> Result<String, serde_urlencoded::ser::Error> {
serde_urlencoded::to_string(SerializableOptions::from(self))
}
}
impl OptionsBuilder {
pub fn new() -> Self {
Self(Options {
start: None,
end: None,
limit: None,
status: None,
})
}
pub fn start(mut self, start: impl Into<String>) -> Self {
self.0.start = Some(start.into());
self
}
pub fn end(mut self, end: impl Into<String>) -> Self {
self.0.end = Some(end.into());
self
}
pub fn limit(mut self, limit: usize) -> Self {
self.0.limit = Some(limit);
self
}
pub fn status(mut self, status: Status) -> Self {
self.0.status = Some(status);
self
}
pub fn build(self) -> Options {
self.0
}
}
impl Default for OptionsBuilder {
fn default() -> Self {
Self::new()
}
}
impl<'a> From<&'a Options> for SerializableOptions<'a> {
fn from(options: &'a Options) -> Self {
let Options {
start,
end,
limit,
status,
} = options;
Self {
start,
end,
limit: *limit,
status: match status {
Some(Status::Succeeded) => Some("succeeded"),
Some(Status::Failed) => Some("failed"),
None => None,
},
}
}
}