use std::time::Duration;
use eframe::egui;
use egui_async::{Bind, EguiAsyncPlugin};
fn main() -> eframe::Result {
let native_options = eframe::NativeOptions::default();
eframe::run_native(
"egui-async example",
native_options,
Box::new(|_cc| Ok(Box::new(MyApp::default()))),
)
}
struct MyApp {
my_ip: Bind<String, String>, }
impl Default for MyApp {
fn default() -> Self {
Self {
my_ip: Bind::new(false),
}
}
}
impl eframe::App for MyApp {
fn logic(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
ctx.plugin_or_default::<EguiAsyncPlugin>(); }
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show_inside(ui, |ui| {
ui.heading("egui-async Demo");
ui.label("This example fetches your public IP address asynchronously.");
ui.separator();
if let Some(res) = self.my_ip.read_or_request(|| async {
reqwest::get("https://icanhazip.com/")
.await
.map_err(|e| e.to_string())?
.text()
.await
.map_err(|e| e.to_string())
}) {
match res {
Ok(ip) => {
ui.label(format!("Your public IP is: {ip}"));
}
Err(err) => {
ui.colored_label(
egui::Color32::RED,
format!("Could not fetch IP.\nError: {err}"),
);
}
}
} else {
ui.spinner();
}
if ui.button("Refresh IP with fragile connection").clicked() {
self.my_ip.refresh(fragile_fetch_data());
}
});
}
}
async fn fragile_fetch_data() -> Result<String, String> {
#[cfg(not(target_family = "wasm"))]
tokio::time::sleep(Duration::from_secs(1)).await;
if rand::random() {
reqwest::get("https://icanhazip.com/")
.await
.map_err(|e| e.to_string())?
.text()
.await
.map_err(|e| e.to_string())
} else {
Err("Failed to fetch data.".to_string())
}
}