app: Create CommonComponent

This is a utility that gathers common parts of components, like task
and error handling.
This commit is contained in:
Valentin Tolmer 2021-10-29 12:31:30 +09:00 committed by nitnelave
parent ba1a5f6011
commit 6c09af6479
2 changed files with 69 additions and 0 deletions

View File

@ -0,0 +1,68 @@
use anyhow::{Error, Result};
use yew::{
prelude::*,
services::{fetch::FetchTask, ConsoleService},
};
pub trait CommonComponent<C: Component + CommonComponent<C>>: Component {
fn handle_msg(&mut self, msg: <Self as Component>::Message) -> Result<bool>;
fn mut_common(&mut self) -> &mut CommonComponentParts<C>;
}
pub struct CommonComponentParts<C: CommonComponent<C>> {
pub link: ComponentLink<C>,
pub props: <C as Component>::Properties,
pub error: Option<Error>,
pub task: Option<FetchTask>,
}
impl<C: CommonComponent<C>> CommonComponentParts<C> {
pub fn create(props: <C as Component>::Properties, link: ComponentLink<C>) -> Self {
Self {
link,
props,
error: None,
task: None,
}
}
pub fn update(com: &mut C, msg: <C as Component>::Message) -> ShouldRender {
com.mut_common().error = None;
match com.handle_msg(msg) {
Err(e) => {
ConsoleService::error(&e.to_string());
com.mut_common().error = Some(e);
true
}
Ok(b) => b,
}
}
pub fn call_backend<M, Req, Cb, Resp>(
&mut self,
method: M,
req: Req,
callback: Cb,
) -> Result<()>
where
M: Fn(Req, Callback<Resp>) -> Result<FetchTask>,
Cb: Fn(Resp) -> <C as Component>::Message + 'static,
{
self.task = Some(method(req, self.link.callback(callback))?);
Ok(())
}
}
impl<C: Component + CommonComponent<C>> std::ops::Deref for CommonComponentParts<C> {
type Target = <C as Component>::Properties;
fn deref(&self) -> &<Self as std::ops::Deref>::Target {
&self.props
}
}
impl<C: Component + CommonComponent<C>> std::ops::DerefMut for CommonComponentParts<C> {
fn deref_mut(&mut self) -> &mut <Self as std::ops::Deref>::Target {
&mut self.props
}
}

View File

@ -1,4 +1,5 @@
pub mod api;
pub mod common_component;
pub mod cookies;
pub mod graphql;
pub mod modal;