use crate::Error;
use crate::option_value::{Block2RequestData, TryFromOption};
use coap_message::MessageOption;
use coap_numbers::option;
pub trait OptionsExt<O: MessageOption>: Iterator<Item = O> {
fn ignore_uri_host(self) -> impl Iterator<Item = O>;
fn ignore_uri_query(self) -> impl Iterator<Item = O>;
fn ignore_elective_others(self) -> Result<(), Error>;
fn take_into<'a, T: TryFromOption>(self, out: &'a mut Option<T>) -> impl Iterator<Item = O>
where
Self: 'a;
fn take_block2<'a>(self, out: &'a mut Option<Block2RequestData>) -> impl Iterator<Item = O>
where
Self: 'a;
fn take_uri_path<F: FnMut(&str)>(self, f: F) -> impl Iterator<Item = O>;
}
impl<T, O> OptionsExt<O> for T
where
T: Iterator<Item = O>,
O: MessageOption,
{
fn ignore_uri_host(self) -> impl Iterator<Item = O> {
self.filter(|o| o.number() != option::URI_HOST)
}
fn ignore_uri_query(self) -> impl Iterator<Item = O> {
self.filter(|o| o.number() != option::URI_QUERY)
}
fn ignore_elective_others(mut self) -> Result<(), Error> {
match self.find(|o| option::get_criticality(o.number()) == option::Criticality::Critical) {
Some(o) => Err(Error::bad_option(o.number())),
None => Ok(()),
}
}
fn take_into<'a, T2: 'a + TryFromOption>(
self,
out: &'a mut Option<T2>,
) -> impl Iterator<Item = O>
where
T: 'a,
{
self.filter(move |o| {
if out.is_none()
&& let Some(o) = T2::try_from(o)
{
*out = Some(o);
return false;
}
true
})
}
fn take_block2<'a>(self, out: &'a mut Option<Block2RequestData>) -> impl Iterator<Item = O>
where
Self: 'a,
{
self.take_into(out)
}
fn take_uri_path<F: FnMut(&str)>(self, mut f: F) -> impl Iterator<Item = O> {
self.filter(move |o| {
if o.number() == option::URI_PATH
&& let Ok(s) = core::str::from_utf8(o.value())
{
f(s);
return false;
}
true
})
}
}