use naan::prelude::MonadOnce;
use toad_array::Array;
use toad_msg::{MessageOptions, OptNumber, OptValue};
use super::{Method, Req};
use crate::option::common_options;
use crate::platform::{self, PlatformTypes};
use crate::ToCoapValue;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error<P>
where P: PlatformTypes,
platform::toad_msg::opt::OptValue<P>: Clone + Eq + core::fmt::Debug,
platform::toad_msg::opt::SetError<P>: Clone + core::fmt::Debug + Eq
{
SetOptionError(platform::toad_msg::opt::SetError<P>),
#[allow(missing_docs)]
OptionNotRepeatable {
number: OptNumber,
old: platform::toad_msg::opt::OptValue<P>,
new: platform::toad_msg::opt::OptValue<P>,
},
}
#[derive(Clone, Debug)]
pub struct ReqBuilder<P>
where P: PlatformTypes,
platform::toad_msg::opt::OptValue<P>: Clone + Eq + core::fmt::Debug,
platform::toad_msg::opt::SetError<P>: Clone + core::fmt::Debug + Eq
{
inner: Result<Req<P>, Error<P>>,
}
impl<P> ReqBuilder<P>
where P: PlatformTypes,
platform::toad_msg::opt::OptValue<P>: Clone + Eq + core::fmt::Debug,
platform::toad_msg::opt::SetError<P>: Clone + core::fmt::Debug + Eq
{
fn new(method: Method, path: impl AsRef<str>) -> Self {
Self { inner: Ok(Req::new(method, path)) }
}
pub fn get(path: impl AsRef<str>) -> Self {
Self::new(Method::GET, path)
}
pub fn put(path: impl AsRef<str>) -> Self {
Self::new(Method::PUT, path)
}
pub fn post(path: impl AsRef<str>) -> Self {
Self::new(Method::POST, path)
}
pub fn delete(path: impl AsRef<str>) -> Self {
Self::new(Method::DELETE, path)
}
pub fn option<V: ToCoapValue>(mut self, number: OptNumber, value: V) -> Self {
self.inner =
self.inner.and_then(|mut req| {
let val = OptValue(value.to_coap_value::<platform::toad_msg::opt::Bytes<P>>());
match req.as_mut().remove(number) {
| Some(existing) => {
Err(Error::OptionNotRepeatable { number,
old: existing.into_iter().next().unwrap(),
new: val })
},
| None => req.msg_mut()
.set(number, val)
.map_err(Error::SetOptionError)
.map(|_| req),
}
});
self
}
pub fn add_option<V: ToCoapValue>(mut self, number: OptNumber, value: V) -> Self {
self.inner = self.inner.and_then(|mut req| {
let val =
OptValue(value.to_coap_value::<platform::toad_msg::opt::Bytes<P>>());
req.msg_mut()
.set(number, val)
.map_err(Error::SetOptionError)
.map(|_| req)
});
self
}
pub fn payload<V: ToCoapValue>(mut self, value: V) -> Self {
self.inner
.as_mut()
.discard_mut(|i: &mut &mut Req<P>| Ok(i.set_payload(value)))
.ok();
self
}
pub fn build(self) -> Result<Req<P>, Error<P>> {
self.inner
}
common_options!(P);
}