106 lines
3.7 KiB
Rust
106 lines
3.7 KiB
Rust
//! Aspirational RUIN app API for runtime-integrated filesystem and network I/O.
|
|
//!
|
|
//! Intentionally non-compiling; this is a design sketch.
|
|
|
|
use ruin::prelude::*;
|
|
|
|
#[ruin_runtime::async_main]
|
|
async fn main() -> ruin::Result<()> {
|
|
App::new()
|
|
.window(Window::new().title("RUIN Runtime I/O").size(1280.0, 820.0))
|
|
.mount::<RuntimeIoExample>()
|
|
.run()
|
|
.await
|
|
}
|
|
|
|
#[component]
|
|
fn RuntimeIoExample() -> impl View {
|
|
let manifest_path = use_signal(|| "./Cargo.toml".to_string());
|
|
let release_url =
|
|
use_signal(|| "https://api.github.com/repos/wtemple/ruin/releases/latest".to_string());
|
|
|
|
let manifest = use_resource(move || {
|
|
let path = manifest_path.get();
|
|
async move { ruin_runtime::fs::read_to_string(path).await }
|
|
});
|
|
|
|
let release = use_resource(move || {
|
|
let url = release_url.get();
|
|
async move { ruin_http::get_json::<ReleaseSummary>(&url).await }
|
|
});
|
|
|
|
let save_snapshot = use_action(move |_| {
|
|
let manifest = manifest.latest_cloned();
|
|
async move {
|
|
let manifest = manifest.ok_or_else(|| anyhow!("manifest is not loaded yet"))?;
|
|
ruin_runtime::fs::write("./tmp/manifest-snapshot.toml", manifest).await?;
|
|
Ok::<_, anyhow::Error>(())
|
|
}
|
|
});
|
|
|
|
use_async_effect(move || {
|
|
let url = release_url.get();
|
|
async move {
|
|
tracing::info!(%url, "release endpoint changed");
|
|
Ok::<_, anyhow::Error>(())
|
|
}
|
|
});
|
|
|
|
view! {
|
|
row(fill = true, gap = 20, padding = 20) {
|
|
block(fill = true, gap = 12) {
|
|
text(role = TextRole::Heading(1), size = 26, weight = FontWeight::Semibold) {
|
|
"Filesystem"
|
|
}
|
|
text_input(value = manifest_path, placeholder = "./Cargo.toml") {}
|
|
|
|
match manifest.read() {
|
|
Pending => view! { ProgressSpinner(label = "Reading file...") {} },
|
|
Ready(Ok(contents)) => view! {
|
|
column(gap = 12) {
|
|
button(
|
|
on_press = save_snapshot.dispatcher(),
|
|
disabled = save_snapshot.pending(),
|
|
) {
|
|
"Save snapshot"
|
|
}
|
|
|
|
CodeBlock(language = "toml") { contents }
|
|
}
|
|
},
|
|
Ready(Err(error)) => view! {
|
|
ErrorPanel(title = "Failed to read file", detail = error.to_string()) {}
|
|
},
|
|
}
|
|
}
|
|
|
|
block(fill = true, gap = 12) {
|
|
text(role = TextRole::Heading(1), size = 26, weight = FontWeight::Semibold) {
|
|
"Network"
|
|
}
|
|
text_input(value = release_url, placeholder = "https://...") {}
|
|
|
|
match release.read() {
|
|
Pending => view! { ProgressSpinner(label = "Fetching release summary...") {} },
|
|
Ready(Ok(release)) => view! {
|
|
column(gap = 8) {
|
|
text(size = 20, weight = FontWeight::Semibold) { release.name.clone() }
|
|
text(color = colors::muted()) { release.published_at.clone() }
|
|
text { release.notes.clone() }
|
|
}
|
|
},
|
|
Ready(Err(error)) => view! {
|
|
ErrorPanel(title = "Failed to fetch release", detail = error.to_string()) {}
|
|
},
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ReleaseSummary {
|
|
name: String,
|
|
published_at: String,
|
|
notes: String,
|
|
}
|