use coap_handler::Handler;
use coap_message::{MinimalWritableMessage, MutableWritableMessage, ReadableMessage};
use coap_handler::{Attribute, Record, Reporting};
pub struct NotReporting<H: Handler>(H);
impl<H: Handler> NotReporting<H> {
pub fn new(handler: H) -> Self {
NotReporting(handler)
}
}
impl<H: Handler> Handler for NotReporting<H> {
type RequestData = H::RequestData;
type ExtractRequestError = H::ExtractRequestError;
type BuildResponseError<M: MinimalWritableMessage> = H::BuildResponseError<M>;
fn extract_request_data<M: ReadableMessage>(
&mut self,
m: &M,
) -> Result<H::RequestData, Self::ExtractRequestError> {
self.0.extract_request_data(m)
}
fn estimate_length(&mut self, r: &Self::RequestData) -> usize {
self.0.estimate_length(r)
}
fn build_response<M: MutableWritableMessage>(
&mut self,
m: &mut M,
r: Self::RequestData,
) -> Result<(), Self::BuildResponseError<M>> {
self.0.build_response(m, r)
}
}
pub struct EmptyRecord;
impl Record for EmptyRecord {
type PathElement = &'static &'static str; type PathElements = core::iter::Empty<&'static &'static str>;
type Attributes = core::iter::Empty<Attribute>;
fn path(&self) -> Self::PathElements {
core::iter::empty()
}
fn rel(&self) -> Option<&str> {
None
}
fn attributes(&self) -> Self::Attributes {
core::iter::empty()
}
}
impl<H: Handler> Reporting for NotReporting<H> {
type Record<'a>
= EmptyRecord
where
Self: 'a;
type Reporter<'a>
= core::iter::Empty<EmptyRecord>
where
Self: 'a;
fn report(&self) -> Self::Reporter<'_> {
core::iter::empty()
}
}
pub struct ConstantSingleRecordReport<'a, H: Handler> {
handler: H,
path: &'a [&'a str],
attributes: &'a [Attribute],
}
impl<'a, H: Handler> ConstantSingleRecordReport<'a, H> {
pub fn new(handler: H, attributes: &'a [Attribute]) -> Self {
ConstantSingleRecordReport {
handler,
path: &[],
attributes,
}
}
pub fn new_with_path(handler: H, attributes: &'a [Attribute], path: &'a [&'a str]) -> Self {
ConstantSingleRecordReport {
handler,
path,
attributes,
}
}
}
impl<H: Handler> Handler for ConstantSingleRecordReport<'_, H> {
type RequestData = H::RequestData;
type ExtractRequestError = H::ExtractRequestError;
type BuildResponseError<M: MinimalWritableMessage> = H::BuildResponseError<M>;
fn extract_request_data<M: ReadableMessage>(
&mut self,
m: &M,
) -> Result<H::RequestData, Self::ExtractRequestError> {
self.handler.extract_request_data(m)
}
fn estimate_length(&mut self, r: &Self::RequestData) -> usize {
self.handler.estimate_length(r)
}
fn build_response<M: MutableWritableMessage>(
&mut self,
m: &mut M,
r: Self::RequestData,
) -> Result<(), Self::BuildResponseError<M>> {
self.handler.build_response(m, r)
}
}
pub struct ConstantSliceRecord<'a> {
path: &'a [&'a str],
attributes: &'a [Attribute],
}
impl<'a> ConstantSliceRecord<'a> {
pub fn new(attributes: &'a [Attribute]) -> Self {
Self {
path: &[],
attributes,
}
}
pub fn new_with_path(path: &'a [&'a str], attributes: &'a [Attribute]) -> Self {
Self { path, attributes }
}
}
impl<'a> Record for ConstantSliceRecord<'a> {
type PathElement = &'a &'a str;
type PathElements = core::slice::Iter<'a, &'a str>;
type Attributes = core::iter::Cloned<core::slice::Iter<'a, Attribute>>;
fn path(&self) -> Self::PathElements {
self.path.iter()
}
fn rel(&self) -> Option<&str> {
None
}
fn attributes(&self) -> Self::Attributes {
self.attributes.iter().cloned()
}
}
impl<H: Handler> Reporting for ConstantSingleRecordReport<'_, H> {
type Record<'b>
= ConstantSliceRecord<'b>
where
Self: 'b;
type Reporter<'b>
= core::iter::Once<ConstantSliceRecord<'b>>
where
Self: 'b;
fn report(&self) -> Self::Reporter<'_> {
core::iter::once(ConstantSliceRecord {
path: self.path,
attributes: self.attributes,
})
}
}
pub fn write_link_format(
w: &mut impl core::fmt::Write,
report: &impl Reporting,
prefix: &[&str],
) -> core::fmt::Result {
let mut first = true;
for record in report.report() {
if !first {
write!(w, ",")?;
} else {
first = false;
}
write!(w, "<")?;
for p in prefix.iter() {
write!(w, "/{p}")?;
}
for p in record.path() {
write!(w, "/{}", p.as_ref())?;
}
write!(w, ">")?;
if let Some(rel) = record.rel() {
write!(w, ";rel=\"{rel}\"")?;
}
for attr in record.attributes() {
attr.write_link_format(w)?;
}
}
report.write_extra_link_format(w, &mut first)?;
Ok(())
}