use dip::{bevy::log::LogPlugin, prelude::*}; use serde::Deserialize; fn main() { App::new() .add_plugin(DesktopPlugin::::new(Root)) .add_plugin(LogPlugin) .add_plugin(UiStatePlugin) .add_plugin(AsyncActionPlugin) .add_startup_system(fetch_all) .add_system(handle_get_ip_address) .add_system(handle_get_ip_address_wrongly) .add_system(handle_get_user_agent) .run(); } #[ui_state] struct UiState { ip_address: GetIpAddress, request_error: RequestError, user_agent: GetUserAgent, } #[derive(Clone, Debug, Deserialize, Default)] pub struct GetIpAddress { origin: String, } #[allow(dead_code)] #[derive(Clone, Debug, Deserialize, Default)] pub struct GetIpAddressWrongly { blabla: String, } #[derive(Clone, Debug, Deserialize, Default)] pub struct GetUserAgent { #[serde(rename = "user-agent")] user_agent: Option, } #[derive(Debug, Clone, Default)] pub struct RequestError { error: Option>, } impl From for RequestError { fn from(error: reqwest::Error) -> Self { RequestError { error: Some(std::sync::Arc::new(error)), } } } #[async_action] impl AsyncActionCreator { async fn get_ip_address() -> GetIpAddress { reqwest::get("https://httpbin.org/ip") .await .unwrap() .json::() .await .unwrap() } async fn get_ip_address_wrongly() -> Result { let res = reqwest::get("https://httpbin.org/ip") .await? .json::() .await?; Ok(res) } async fn get_user_agent() -> GetUserAgent { static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),); let client = reqwest::Client::builder() .user_agent(APP_USER_AGENT) .build() .unwrap(); client .get("https://httpbin.org/user-agent") .send() .await .unwrap() .json::() .await .unwrap() } } fn fetch_all(async_action: Res>) { async_action.send(AsyncAction::get_ip_address()); async_action.send(AsyncAction::get_ip_address_wrongly()); async_action.send(AsyncAction::get_user_agent()); } fn handle_get_ip_address( mut actions: EventReader, mut ip_address: ResMut, ) { for action in actions.iter() { *ip_address = action.clone(); } } fn handle_get_ip_address_wrongly( mut actions: EventReader>, mut request_error: ResMut, ) { for action in actions.iter() { if let Err(e) = action { *request_error = e.clone(); } } } fn handle_get_user_agent( mut actions: EventReader, mut user_agent: ResMut, ) { for action in actions.iter() { *user_agent = action.clone(); } } #[allow(non_snake_case)] fn Root(cx: Scope) -> Element { let ip_address = use_read(&cx, IP_ADDRESS); let user_agent = use_read(&cx, USER_AGENT); let request_error = use_read(&cx, REQUEST_ERROR); cx.render(rsx! { ul { li { "ip address: {ip_address.origin}" } li { "user_agent: {user_agent.user_agent:?}" } li { "request_error: {request_error.error:?}" } } }) }