Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
523 changes: 190 additions & 333 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ categories = [

[dependencies]
# Simpler error handling
anyhow = "1.0.98"
anyhow = "1.0.99"
# Get current date and time
chrono = { version = "0.4.41", default-features = false, features = ["clock"] }
# Framework for parsing CLI args
clap = { version = "4.5.41", features = ["derive"] }
clap = { version = "4.5.45", features = ["derive"] }
# Detect message boundaries in serial port output from device
cobs = "0.4.0"
# Generate PNG images (sign chunks)
Expand All @@ -35,40 +35,41 @@ data-encoding = "2.9.0"
# Find the best place to sotre the VFS
directories = "6.0.0"
# Serialize app config into meta file in the ROM
firefly-types = { version = "0.5.1" }
firefly-types = { version = "0.6.1" }
# Decode wav files
hound = "3.5.1"
# Parse PNG images
image = { version = "0.25.6", default-features = false, features = ["png"] }
# Generate PNG images (compress frame)
libflate = "2.1.0"
# Random device name generation
# NOTE: Cannot be updated to 0.9.0+ until rsa is updated to 0.10.0+.
rand = "0.8.5"
# Signatures
rsa = { version = "0.9.8", default-features = false, features = [
"std",
"sha2",
] }
rust-embed = { version = "8.7.1", default-features = false, features = [
rust-embed = { version = "8.7.2", default-features = false, features = [
"debug-embed",
] }
# REPL
rustyline = "15.0.0"
rustyline = "17.0.1"
# Deserialize firefly.toml (required by `toml`)
serde = { version = "1.0.219", features = ["serde_derive", "derive"] }
# Deserialize JSON API responses from the firefly catalog
serde_json = "1.0.140"
serde_json = "1.0.143"
# Communicating with running device
serialport = "4.7.1"
serialport = "4.7.2"
# Calculate file checksum
sha2 = "0.10.9"
# Deserialize firefly.toml
toml = "0.8.22"
toml = "0.9.5"
# Download remote files (`url` field in `firefly.toml`)
ureq = "2.12.1"
ureq = "3.1.0"
# Build together post-processed wasm binaries
wasm-encoder = "0.237.0"
# Parse wasm binaries for post-processing (removing custom sections)
wasmparser = "0.237.0"
# Work with zip archives (distribution format for ROMs)
zip = { version = "4.3.0", default-features = false, features = ["zstd"] }
zip = { version = "4.5.0", default-features = false, features = ["zstd"] }
7 changes: 2 additions & 5 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ fn convert_file(name: &str, config: &Config, file_config: &FileConfig) -> anyhow
Ok(())
}

/// If file doesn't exist, donload it from `url` and validate `sha256`.
/// If file doesn't exist, download it from `url` and validate `sha256`.
fn download_file(input_path: &Path, file_config: &FileConfig) -> anyhow::Result<()> {
if input_path.exists() {
return Ok(());
Expand All @@ -217,10 +217,7 @@ fn download_file(input_path: &Path, file_config: &FileConfig) -> anyhow::Result<
bail!("file does not exist and no url specified");
};
let resp = ureq::get(url).call().context("send request")?;
let mut bytes: Vec<u8> = vec![];
resp.into_reader()
.read_to_end(&mut bytes)
.context("read response")?;
let bytes = resp.into_body().read_to_vec().context("read response")?;
if let Some(expected_hash) = &file_config.sha256 {
let mut hasher = Sha256::new();
hasher.update(&bytes);
Expand Down
21 changes: 7 additions & 14 deletions src/commands/catalog.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::args::{CatalogListArgs, CatalogShowArgs};
use anyhow::{bail, Context, Result};
use anyhow::{Context, Result};
use crossterm::style::Stylize;
use serde::Deserialize;
use std::collections::HashMap;
Expand Down Expand Up @@ -39,11 +39,8 @@ struct Author {

pub fn cmd_catalog_list(_args: &CatalogListArgs) -> Result<()> {
let resp = ureq::get(LIST_URL).call().context("send request")?;
if resp.status() != 200 || resp.header("Content-Type") != Some("application/json") {
bail!("cannot connect to the catalog")
}
let apps: Vec<ShortApp> =
serde_json::from_reader(&mut resp.into_reader()).context("parse JSON")?;
let mut body = resp.into_body().into_reader();
let apps: Vec<ShortApp> = serde_json::from_reader(&mut body).context("parse JSON")?;
let id_width = apps.iter().map(|app| app.id.len()).max().unwrap();
for app in apps {
println!(
Expand All @@ -70,10 +67,8 @@ pub fn cmd_catalog_show(args: &CatalogShowArgs) -> Result<()> {
pub fn show_app(args: &CatalogShowArgs) -> Result<()> {
let url = format!("{BASE_URL}{}.json", args.id);
let resp = ureq::get(&url).call().context("send request")?;
if resp.status() != 200 || resp.header("Content-Type") != Some("application/json") {
bail!("the app not found")
}
let app: App = serde_json::from_reader(&mut resp.into_reader()).context("parse JSON")?;
let mut body = resp.into_body().into_reader();
let app: App = serde_json::from_reader(&mut body).context("parse JSON")?;
println!("{} {}", col("title"), app.name);
println!("{} {}", col("author"), app.author.name);
println!("{} {}", col("added"), app.added);
Expand All @@ -96,10 +91,8 @@ pub fn show_app(args: &CatalogShowArgs) -> Result<()> {
pub fn show_author(args: &CatalogShowArgs) -> Result<()> {
let url = format!("{BASE_URL}{}.json", args.id);
let resp = ureq::get(&url).call().context("send request")?;
if resp.status() != 200 || resp.header("Content-Type") != Some("application/json") {
bail!("the author not found")
}
let aut: Author = serde_json::from_reader(&mut resp.into_reader()).context("parse JSON")?;
let mut body = resp.into_body().into_reader();
let aut: Author = serde_json::from_reader(&mut body).context("parse JSON")?;
println!("{} {}", col("name"), aut.name);
if let Some(pronouns) = aut.pronouns {
println!("{} {}", col("pronouns"), pronouns);
Expand Down
13 changes: 7 additions & 6 deletions src/commands/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ fn fetch_archive(path: &str) -> Result<PathBuf> {
if !path.ends_with(".zip") {
let url = format!("https://catalog.fireflyzero.com/{path}.json");
let resp = ureq::get(&url).call().context("send HTTP request")?;
if resp.status() == 200 && resp.header("Content-Type") == Some("application/json") {
let app: CatalogApp =
serde_json::from_reader(&mut resp.into_reader()).context("parse JSON")?;
path = app.download;
}
let mut body = resp.into_body().into_reader();
let app: CatalogApp = serde_json::from_reader(&mut body).context("parse JSON")?;
// TODO(@orsinium): the download link might be a download page,
// not the actual ROM file.
path = app.download;
}

// Local path is given. Just use it.
Expand All @@ -79,7 +79,8 @@ fn fetch_archive(path: &str) -> Result<PathBuf> {
let resp = ureq::get(&path).call().context("send HTTP request")?;
let out_path = temp_dir().join("rom.zip");
let mut file = File::create(&out_path)?;
std::io::copy(&mut resp.into_reader(), &mut file).context("write response into a file")?;
let mut body = resp.into_body().into_reader();
std::io::copy(&mut body, &mut file).context("write response into a file")?;
println!("⌛ installing...");
Ok(out_path)
}
Expand Down
10 changes: 2 additions & 8 deletions src/commands/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,8 @@ fn download_key(url: &str) -> anyhow::Result<(String, Vec<u8>)> {
let Some(author) = file_name.strip_suffix(".der") else {
bail!("the key file must have .der extension")
};
let resp = ureq::get(url).call()?;
let mut buf: Vec<u8> = Vec::new();
let status = resp.status();
if status >= 400 {
let text = resp.status_text();
bail!("cannot download the key: {status} ({text})",)
}
resp.into_reader().read_to_end(&mut buf)?;
let resp = ureq::get(url).call().context("download the key")?;
let buf = resp.into_body().read_to_vec()?;
Ok((author.to_string(), buf))
}

Expand Down
13 changes: 8 additions & 5 deletions src/commands/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,27 +126,30 @@ fn request_device_stats(stream: &mut SerialStream, stats: &mut Stats) -> Result<
}

fn parse_stats(stats: &mut Stats, resp: serial::Response) {
use serial::Response::*;
match resp {
serial::Response::Cheat(_) => {}
serial::Response::Log(log) => {
Log(log) => {
let now = chrono::Local::now().format("%H:%M:%S");
let log = format!("[{now}] {log}");
stats.log = Some(log);
}
serial::Response::Fuel(cb, fuel) => {
Fuel(cb, fuel) => {
use serial::Callback::*;
match cb {
Update => stats.update = Some(fuel),
Render => stats.render = Some(fuel),
RenderLine | Cheat | Boot => {}
}
}
serial::Response::CPU(cpu) => {
CPU(cpu) => {
if cpu.total_ns > 0 {
stats.cpu = Some(cpu);
}
}
serial::Response::Memory(mem) => stats.mem = Some(mem),
Memory(mem) => {
stats.mem = Some(mem);
}
_ => {}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl<'a> Commander<'a> {
/// Download a file from the give URL and save it into the given path.
fn wget(&self, path: &[&str], url: &str) -> Result<()> {
let resp = ureq::get(url).call().context("send request")?;
let mut reader = resp.into_reader();
let mut reader = resp.into_body().into_reader();
let mut full_path = self.root.unwrap().to_path_buf();
for part in path {
full_path = full_path.join(part);
Expand Down