One complicating factor is that different methods may return different types. Most of them return a String currently, but for example .header() would return an Option<String>.
This means that functions like Dom::method() and Dom::path() are essentially the same, and differ only in the type they tx.send(), and differ from .header() in the type they return. I wonder if I can use some generics trickery to remove the boilerplate.
Hah! I CAN!
impl Dom {
fn communicate<T, F>(&self, req: F) -> T
where
F: FnOnce(oneshot::Sender<T>) -> DomRequest,
{
let (resp_tx, resp_rx) = oneshot::channel();
let tx = self.channel.clone();
tx.send(req(resp_tx)).ok().unwrap();
tokio::task::block_in_place(move || resp_rx.blocking_recv().unwrap())
}
pub fn method(&self) -> String {
self.communicate(|responder| DomRequest::Method { responder })
}
}
Sweet.