use coap_message::heapmessage::HeapMessage;
use coap_message::{MinimalWritableMessage, ReadableMessage, MessageOption};
use crate::binentry;
#[derive(Debug)]
pub enum EditMsg {
ChangeCode(u8),
ChangePayload(Vec<u8>),
ChangeOpt(u16, usize, Vec<u8>),
RemoveOpt(u16, usize),
AddOptSet(u16),
AddOptDo,
}
pub struct EditorState {
add_coapopt: u16,
}
impl Default for EditorState {
fn default() -> Self { Self { add_coapopt: 4 } }
}
pub fn apply(change: EditMsg, coapmessage: &mut HeapMessage, editorstate: &mut EditorState) {
match change {
EditMsg::ChangeCode(c) => {
coapmessage.set_code(c);
}
EditMsg::ChangePayload(p) => {
coapmessage.set_payload(&p);
}
EditMsg::ChangeOpt(optnum, index, value) => {
coapmessage.change_option(optnum, index, value);
}
EditMsg::RemoveOpt(optnum, index) => {
coapmessage.remove_option(optnum, index);
}
EditMsg::AddOptDo => {
coapmessage.add_option(editorstate.add_coapopt, &[]);
}
EditMsg::AddOptSet(o) => {
editorstate.add_coapopt = o;
}
}
}
pub fn render<COMP: yew::Component>(coapmessage: &HeapMessage, editorstate: &EditorState, link: &yew::html::Scope<COMP>, wrap: impl 'static + Copy + Fn(EditMsg) -> COMP::Message) -> yew::virtual_dom::vnode::VNode {
use yew::prelude::*;
html!{<>
<p><label> {"Code:"}
<input
type="number"
value=coapmessage.code()
onchange=link.callback(move |v| wrap(EditMsg::ChangeCode(match v {
yew::events::ChangeData::Value(s) => s.parse().expect("Numeric input is numeric"),
_ => unreachable!("Numeric input has value"),
})))
/>
{ " " } { coap_numbers::code::to_dotted(coapmessage.code()) }
{ " " } { coap_numbers::code::to_name(coapmessage.code()).unwrap_or("unknown") } </label></p>
<ul> {
for coapmessage.options()
.map({
let mut occurrence = 0;
let mut last_opt = 0;
move |opt| {
if opt.number() != last_opt {
last_opt = opt.number();
occurrence = 0;
}
let ret = (occurrence, opt);
occurrence += 1;
ret
}
})
.map(|(i, opt)| { let optnum = opt.number(); html!{
<li> { format!("{} #{}: {} ", optnum, i, coap_numbers::option::to_name(optnum).unwrap_or("unknown")) }
<binentry::BinaryEntry
onchange=link.callback(move |v| wrap(EditMsg::ChangeOpt(optnum, i, v)))
value=opt.value().to_vec()
/>
<button onclick=link.callback(move |_| wrap(EditMsg::RemoveOpt(optnum, i)))> { "x" } </button>
</li>
}})}
<li>
{ "New: " }
<input
type="number"
value=editorstate.add_coapopt
onchange=link.callback(move |v| wrap(EditMsg::AddOptSet(match v {
yew::events::ChangeData::Value(s) => s.parse().expect("Numeric input is numeric"),
_ => unreachable!("Numeric input has value"),
})))
/>
{ coap_numbers::option::to_name(editorstate.add_coapopt).unwrap_or("") }
<button onclick=link.callback(move |_| wrap(EditMsg::AddOptDo))> { "+" } </button>
</li>
</ul>
<p><label> {"Payload:"} <br /><binentry::BinaryEntry
onchange=link.callback(move |v| wrap(EditMsg::ChangePayload(v)))
value=coapmessage.payload().to_vec()
textarea=true
/></label></p>
</>}
}