Commit f8c8b5e0 authored by chrysn's avatar chrysn

Implement process_uri_path as it should be

parent 51dc6e76
Pipeline #181174899 failed with stage
in 3 minutes and 9 seconds
......@@ -110,11 +110,9 @@ impl ColorServer {
}
let mut path = Path::Root;
crate::util::process_uri_path(
request.options()
request.options()
.ignore_uri_host()
// FIXME use as a trait method
, |p| path = path.push(p))
.process_uri_path(|p| path = path.push(p))
.ignore_elective_others()
// Any critical option was left over
.map_err(|_| code::BAD_REQUEST)?;
......
#![recursion_limit="1024"]
#![feature(type_alias_impl_trait)]
#![feature(generic_associated_types)]
mod coapws;
mod binentry;
......
......@@ -10,9 +10,21 @@ use coap_message::MessageOption;
pub trait OptionsExt<O: MessageOption>: Iterator<Item=O> {
type IgnoredUriHost: Iterator<Item=O> + Sized;
type ProcessUriPathOutput<F>: Iterator<Item=O> + Sized;
fn ignore_uri_host(self) -> Self::IgnoredUriHost;
/// Call a function (that typically cranks some path state machine) on every (valid) Uri-Path
/// option in an iterator, hiding them from further iteration.
///
/// Error handling of the UTF8 decoding is done by not removing invalid options from the iterator,
/// thus leaving them for an eventual ignore_elective_others.
///
/// FIXME Provide an analogous function that doesn't care about UTF-8. This needs the state
/// machines to run on &[u8], but allows eliding the check (especially as mostly this they will do
/// comparisons or something like atoi).
fn process_uri_path<F: FnMut(&str)>(self, f: F) -> Self::ProcessUriPathOutput<F>;
fn ignore_elective_others(self) -> Result<(), CriticalOptionsRemain>;
}
......@@ -22,6 +34,7 @@ where
O: MessageOption,
{
type IgnoredUriHost = core::iter::Filter<Self, fn(&O) -> bool>;
type ProcessUriPathOutput<F> = impl Iterator<Item=O> + Sized;
fn ignore_uri_host(self) -> Self::IgnoredUriHost {
fn keep_option<O: MessageOption>(o: &O) -> bool {
......@@ -39,38 +52,17 @@ where
None => Ok(())
}
}
}
/// Call a function (that typically cranks some path state machine) on every (valid) Uri-Path
/// option in an iterator, hiding them from further iteration.
///
/// Error handling of the UTF8 decoding is done by not removing invalid options from the iterator,
/// thus leaving them for an eventual ignore_elective_others.
///
/// FIXME This should become a trait method of OptionsExt, but currently can't be because it'd need
/// to say
///
/// type IgnoreUriHost<F>: impl Iterator<Item=O> + Sized;
/// fn process_uri_path<F>(self, f: F) -> impl Iterator<Item=O>;
///
/// which not only needs RFC 2515 but even more them being generic.
///
/// FIXME Provide an analogous function that doesn't care about UTF-8. This needs the state
/// machines to run on &[u8], but allows eliding the check (especially as mostly this they will do
/// comparisons or something like atoi).
pub fn process_uri_path<I, O, F>(iter: I, mut f: F) -> impl Iterator<Item=O>
where
O: MessageOption,
I: Iterator<Item=O>,
F: FnMut(&str),
{
iter.filter(move |o| {
if o.number() == option::URI_PATH {
if let Ok(s) = core::str::from_utf8(o.value()) {
f(s);
return false;
fn process_uri_path<F: FnMut(&str)>(self, mut f: F) -> Self::ProcessUriPathOutput<F>
{
self.filter(move |o| {
if o.number() == option::URI_PATH {
if let Ok(s) = core::str::from_utf8(o.value()) {
f(s);
return false;
}
}
}
true
})
true
})
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment