From 41d2cc8658c077b2b38206118db501602a66cdf3 Mon Sep 17 00:00:00 2001 From: ferris Date: Mon, 7 Apr 2025 00:17:30 +0200 Subject: [PATCH 1/6] Add no_std support w/ alloc & embedded-io --- Cargo.lock | 173 ++++++------ espflash/Cargo.toml | 29 +- espflash/src/cli/mod.rs | 16 +- espflash/src/{connection => }/command.rs | 14 +- espflash/src/connection/mod.rs | 25 +- espflash/src/error.rs | 298 +++++++++++++-------- espflash/src/flasher/mod.rs | 40 ++- espflash/src/image_format/esp_idf.rs | 73 +++-- espflash/src/image_format/metadata.rs | 12 +- espflash/src/image_format/mod.rs | 12 +- espflash/src/lib.rs | 6 +- espflash/src/targets/esp32.rs | 2 +- espflash/src/targets/esp32c2.rs | 7 +- espflash/src/targets/esp32c3.rs | 2 +- espflash/src/targets/esp32c6.rs | 2 +- espflash/src/targets/esp32h2.rs | 7 +- espflash/src/targets/esp32p4.rs | 2 +- espflash/src/targets/esp32s2.rs | 2 +- espflash/src/targets/esp32s3.rs | 2 +- espflash/src/targets/flash_target/esp32.rs | 6 +- espflash/src/targets/flash_target/ram.rs | 6 +- espflash/src/targets/mod.rs | 18 +- 22 files changed, 426 insertions(+), 328 deletions(-) rename espflash/src/{connection => }/command.rs (98%) diff --git a/Cargo.lock b/Cargo.lock index 9b354cd7..c8cd3fe1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -282,7 +282,7 @@ checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -384,7 +384,7 @@ dependencies = [ "thiserror 1.0.69", "time", "toml", - "toml_edit 0.22.22", + "toml_edit", "tracing", "tracing-chrome", "tracing-subscriber", @@ -569,7 +569,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", "terminal_size", ] @@ -594,7 +594,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -627,7 +627,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -891,9 +891,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -901,27 +901,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 1.0.109", + "strsim", + "syn", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -980,25 +980,27 @@ dependencies = [ [[package]] name = "deku" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819b87cc7a05b3abe3fc38e59b3980a5fd3162f25a247116441a9171d3e84481" +checksum = "709ade444d53896e60f6265660eb50480dd08b77bfc822e5dcc233b88b0b2fba" dependencies = [ "bitvec", "deku_derive", + "no_std_io", + "rustversion", ] [[package]] name = "deku_derive" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2ca12572239215a352a74ad7c776d7e8a914f8a23511c6cbedddd887e5009e" +checksum = "d7534973f93f9de83203e41c8ddd32d230599fa73fa889f3deb1580ccd186913" dependencies = [ "darling", "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1076,7 +1078,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -1141,6 +1143,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io-adapters" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03facd2b544d24916f312a6026c1b548b8af012f788a554d498afdc8ef9c775" +dependencies = [ + "embedded-io", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -1208,19 +1225,16 @@ dependencies = [ [[package]] name = "esp-idf-part" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f50b6c32370067087b46087cd5333f2dfe678f0b01223fa70fde6f15449844" dependencies = [ "csv", "deku", - "heapless", - "md5", + "md-5", "parse_int", "regex", "serde", "serde_plain", "strum", - "thiserror 1.0.69", + "thiserror 2.0.10", ] [[package]] @@ -1239,9 +1253,12 @@ dependencies = [ "defmt-decoder", "dialoguer", "directories", + "embedded-io", + "embedded-io-adapters", "env_logger", "esp-idf-part", "flate2", + "heapless", "indicatif", "libc", "log", @@ -1558,7 +1575,7 @@ dependencies = [ "gix-utils", "itoa", "thiserror 2.0.10", - "winnow 0.6.22", + "winnow", ] [[package]] @@ -1640,7 +1657,7 @@ dependencies = [ "smallvec", "thiserror 2.0.10", "unicode-bom", - "winnow 0.6.22", + "winnow", ] [[package]] @@ -1906,7 +1923,7 @@ dependencies = [ "itoa", "smallvec", "thiserror 2.0.10", - "winnow 0.6.22", + "winnow", ] [[package]] @@ -2038,7 +2055,7 @@ dependencies = [ "gix-utils", "maybe-async", "thiserror 2.0.10", - "winnow 0.6.22", + "winnow", ] [[package]] @@ -2070,7 +2087,7 @@ dependencies = [ "gix-validate", "memmap2", "thiserror 2.0.10", - "winnow 0.6.22", + "winnow", ] [[package]] @@ -2336,7 +2353,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ "hash32", - "serde", "stable_deref_trait", ] @@ -2605,7 +2621,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -2964,7 +2980,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -2977,12 +2993,6 @@ dependencies = [ "digest", ] -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - [[package]] name = "memchr" version = "2.7.4" @@ -3026,7 +3036,7 @@ checksum = "23c9b935fbe1d6cbd1dac857b54a688145e2d93f48db36010514d0f612d0ad67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -3094,6 +3104,15 @@ dependencies = [ "libc", ] +[[package]] +name = "no_std_io" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fa5f306a6f2c01b4fd172f29bb46195b1764061bf926c75e96ff55df3178208" +dependencies = [ + "memchr", +] + [[package]] name = "nom" version = "7.1.3" @@ -3205,7 +3224,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -3439,12 +3458,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "toml_edit", ] [[package]] @@ -3935,7 +3953,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -4171,12 +4189,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -4202,7 +4214,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.96", + "syn", ] [[package]] @@ -4232,17 +4244,6 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.96" @@ -4271,7 +4272,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -4350,7 +4351,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -4361,7 +4362,7 @@ checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -4464,7 +4465,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -4476,17 +4477,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.22" @@ -4497,7 +4487,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.22", + "winnow", ] [[package]] @@ -4546,7 +4536,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -4824,7 +4814,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.96", + "syn", "wasm-bindgen-shared", ] @@ -4859,7 +4849,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5108,15 +5098,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.22" @@ -5167,7 +5148,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", "synstructure", ] @@ -5189,7 +5170,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] [[package]] @@ -5209,7 +5190,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", "synstructure", ] @@ -5238,5 +5219,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn", ] diff --git a/espflash/Cargo.toml b/espflash/Cargo.toml index bba64204..0b00ceb2 100644 --- a/espflash/Cargo.toml +++ b/espflash/Cargo.toml @@ -26,7 +26,7 @@ required-features = ["cli", "serialport"] [dependencies] addr2line = { version = "0.24.2", optional = true } -base64 = "0.22.1" +base64 = { version = "0.22.1", default-features = false } bitflags = "2.9.0" bytemuck = { version = "1.21.0", features = ["derive"] } clap = { version = "4.5.24", features = ["derive", "env", "wrap_help"], optional = true } @@ -38,23 +38,27 @@ defmt-decoder = { version = "=0.4.0", features = ["unstable"], optional = true dialoguer = { version = "0.11.0", optional = true } directories = { version = "5.0.1", optional = true } env_logger = { version = "0.11.6", optional = true } -esp-idf-part = "0.5.0" -flate2 = "1.0.35" +esp-idf-part = { path = "../../esp-idf-part", default-features = false } +flate2 = { version = "1.0.35", optional = true } indicatif = { version = "0.17.9", optional = true } log = "0.4.22" -md-5 = "0.10.6" -miette = "7.4.0" -object = "0.36.7" +md-5 = { version = "0.10.6", default-features = false} +miette = { version = "7.4.0", optional = true} +object = { version = "0.36.7", default-features = false, features = ['read'] } regex = { version = "1.11.1", optional = true } -serde = { version = "1.0.217", features = ["derive"] } +serde = { version = "1.0.217", features = ["derive"], default-features = false } serialport = { version = "4.7.0", default-features = false, optional = true } -sha2 = "0.10.8" +sha2 = { version = "0.10.8", default-features = false} slip-codec = { version = "0.4.0", optional = true } -strum = { version = "0.26.3", features = ["derive"] } -thiserror = "2.0.10" +strum = { version = "0.26.3", default-features = false, features = ["derive"] } +thiserror = { version = "2.0.10", default-features = false } toml = { version = "0.8.19", optional = true } update-informer = { version = "1.2.0", optional = true } +heapless = { version = "0.8.0" } +embedded-io = { version = "0.6.1", features = ["alloc"]} +embedded-io-adapters = { version = "0.6.1"} + [target.'cfg(unix)'.dependencies] libc = "0.2.169" @@ -75,7 +79,10 @@ cli = [ "dep:update-informer", "miette/fancy", "serialport", + "std" ] # Enables connecting to a device via serial port -serialport = ["dep:regex", "dep:serialport", "dep:slip-codec", "dep:toml"] +serialport = ["dep:regex", "dep:serialport", "dep:slip-codec", "dep:toml", "std"] + +std = ["dep:miette", "dep:flate2", "object/default", "serde/std", "thiserror/std", "strum/std", "esp-idf-part/std", "md-5/std", "sha2/std", "base64/std", "embedded-io/std", "embedded-io-adapters/std"] diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index 85fc97a4..1aa12ebd 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -11,13 +11,15 @@ //! [espflash]: https://crates.io/crates/espflash use std::{ - collections::HashMap, fs::{self, File}, io::{Read, Write}, num::ParseIntError, path::{Path, PathBuf}, }; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; + use clap::{Args, ValueEnum}; use clap_complete::Shell; use comfy_table::{modifiers, presets::UTF8_FULL, Attribute, Cell, Color, Table}; @@ -35,13 +37,7 @@ use crate::{ connection::reset::{ResetAfterOperation, ResetBeforeOperation}, error::{Error, MissingPartition, MissingPartitionTable}, flasher::{ - FlashData, - FlashFrequency, - FlashMode, - FlashSettings, - FlashSize, - Flasher, - ProgressCallbacks, + FlashData, FlashFrequency, FlashMode, FlashSettings, FlashSize, Flasher, ProgressCallbacks, FLASH_SECTOR_SIZE, }, image_format::Metadata, @@ -830,7 +826,7 @@ pub fn erase_partitions( .ok_or_else(|| MissingPartition::from(label))?; parts_to_erase - .get_or_insert(HashMap::new()) + .get_or_insert(BTreeMap::new()) .insert(part.offset(), part); } } @@ -845,7 +841,7 @@ pub fn erase_partitions( && part.subtype() == esp_idf_part::SubType::Data(ty) { parts_to_erase - .get_or_insert(HashMap::new()) + .get_or_insert(BTreeMap::new()) .insert(part.offset(), part); } } diff --git a/espflash/src/connection/command.rs b/espflash/src/command.rs similarity index 98% rename from espflash/src/connection/command.rs rename to espflash/src/command.rs index f53323fa..e82697bd 100644 --- a/espflash/src/connection/command.rs +++ b/espflash/src/command.rs @@ -1,6 +1,8 @@ //! Commands to work with a flasher stub running on a target device -use std::{io::Write, mem::size_of, time::Duration}; +use core::{mem::size_of, time::Duration}; + +use embedded_io::Write; use bytemuck::{bytes_of, Pod, Zeroable}; use strum::Display; @@ -81,7 +83,7 @@ impl CommandType { pub fn timeout_for_size(&self, size: u32) -> Duration { fn calc_timeout(timeout_per_mb: Duration, size: u32) -> Duration { let mb = size as f64 / 1_000_000.0; - std::cmp::max( + core::cmp::max( FLASH_DEFLATE_END_TIMEOUT, Duration::from_millis((timeout_per_mb.as_millis() as f64 * mb) as u64), ) @@ -238,7 +240,7 @@ impl Command<'_> { } /// Write a command - pub fn write(&self, mut writer: W) -> std::io::Result<()> { + pub fn write(&self, mut writer: W) -> Result<(), W::Error> { // Write the Direction and Command Indentifier writer.write_all(&[0, self.command_type() as u8])?; match *self { @@ -456,7 +458,7 @@ impl Command<'_> { } /// Write a data array and its checksum to a writer -fn write_basic(mut writer: W, data: &[u8], checksum: u32) -> std::io::Result<()> { +fn write_basic(mut writer: W, data: &[u8], checksum: u32) -> Result<(), W::Error> { writer.write_all(&((data.len() as u16).to_le_bytes()))?; writer.write_all(&(checksum.to_le_bytes()))?; writer.write_all(data)?; @@ -471,7 +473,7 @@ fn begin_command( block_size: u32, offset: u32, supports_encryption: bool, -) -> std::io::Result<()> { +) -> Result<(), W::Error> { #[derive(Zeroable, Pod, Copy, Clone, Debug)] #[repr(C)] struct BeginParams { @@ -508,7 +510,7 @@ fn data_command( pad_to: usize, pad_byte: u8, sequence: u32, -) -> std::io::Result<()> { +) -> Result<(), W::Error> { #[derive(Zeroable, Pod, Copy, Clone, Debug)] #[repr(C)] struct BlockParams { diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index 106c5a8c..006033b0 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -4,13 +4,15 @@ //! sending/decoding of commands, and provides higher-level operations with the //! device. +#[cfg(feature = "std")] use std::{ io::{BufWriter, Read, Write}, - iter::zip, thread::sleep, - time::Duration, }; +use core::iter::zip; +use core::time::Duration; + use log::{debug, info}; use regex::Regex; use serialport::{SerialPort, UsbPortInfo}; @@ -22,15 +24,8 @@ use self::{ command::{Command, CommandType}, encoder::SlipEncoder, reset::{ - construct_reset_strategy_sequence, - hard_reset, - reset_after_flash, - soft_reset, - ClassicReset, - ResetAfterOperation, - ResetBeforeOperation, - ResetStrategy, - UsbJtagSerialReset, + construct_reset_strategy_sequence, hard_reset, reset_after_flash, soft_reset, ClassicReset, + ResetAfterOperation, ResetBeforeOperation, ResetStrategy, UsbJtagSerialReset, }, }; use crate::{ @@ -38,7 +33,7 @@ use crate::{ targets::Chip, }; -pub(crate) mod command; +use super::command; pub(crate) mod reset; const MAX_CONNECT_ATTEMPTS: usize = 7; @@ -513,9 +508,9 @@ impl Connection { serial.clear(serialport::ClearBuffer::Input)?; let mut writer = BufWriter::new(serial); - let mut encoder = SlipEncoder::new(&mut writer)?; + let mut encoder = embedded_io_adapters::std::FromStd::new(SlipEncoder::new(&mut writer)?); command.write(&mut encoder)?; - encoder.finish()?; + encoder.into_inner().finish()?; writer.flush()?; Ok(()) } @@ -608,7 +603,7 @@ impl Connection { } mod encoder { - use std::io::Write; + use super::Write; const END: u8 = 0xC0; const ESC: u8 = 0xDB; diff --git a/espflash/src/error.rs b/espflash/src/error.rs index cfa2f5cb..f5a81366 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -2,9 +2,16 @@ #[cfg(feature = "serialport")] use std::fmt::{Display, Formatter}; -use std::{array::TryFromSliceError, io}; +use core::array::TryFromSliceError; +use core::convert::Infallible; + +#[cfg(feature = "std")] +use std::io; + +#[cfg(feature = "std")] use miette::Diagnostic; + #[cfg(feature = "serialport")] use slip_codec::SlipError; use strum::VariantNames; @@ -13,141 +20,174 @@ use thiserror::Error; #[cfg(feature = "cli")] use crate::cli::monitor::parser::esp_defmt::DefmtError; #[cfg(feature = "serialport")] -use crate::connection::command::CommandType; +use crate::command::CommandType; use crate::{ flasher::{FlashFrequency, FlashSize}, targets::Chip, }; +use alloc::string::String; +use alloc::vec::Vec; + /// All possible errors returned by espflash -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] +#[cfg_attr(feature = "std", derive(Diagnostic))] #[non_exhaustive] pub enum Error { #[error("App partition not found")] - #[diagnostic(code(espflash::app_partition_not_found))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::app_partition_not_found)))] AppPartitionNotFound, #[error("Operation was cancelled by the user")] - #[diagnostic(code(espflash::cancelled))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::cancelled)))] Cancelled, #[error("{0}")] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::chip_detect_error), help("Supported chips are: {}\n\ If your chip is supported, try hard-resetting the device and try again", Chip::VARIANTS.join(", ")) - )] + ))] ChipDetectError(String), #[error("Chip provided with `-c/--chip` ({0}) does not match the detected chip ({1})")] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::chip_mismatch), help("Ensure that the correct chip is selected, or remove the `-c/--chip` option to autodetect the chip") - )] + ))] ChipMismatch(String, String), #[error("Chip not argument provided, this is required when using the `--before no-reset-no-sync` option")] - #[diagnostic( - code(espflash::chip_not_provided), - help("Ensure that you provide the `-c/--chip` option with the proper chip") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::chip_not_provided), + help("Ensure that you provide the `-c/--chip` option with the proper chip") + ) )] ChipNotProvided, #[error("Corrupt data, expected {0:2x?} bytes but receved {1:2x?} bytes")] - #[diagnostic(code(espflash::read_flash::corrupt_data))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::read_flash::corrupt_data)))] CorruptData(usize, usize), #[error("MD5 digest missmatch: expected {0:2x?}, received: {1:2x?}")] - #[diagnostic(code(espflash::read_flash::digest_mismatch))] + #[cfg_attr( + feature = "std", + diagnostic(code(espflash::read_flash::digest_mismatch)) + )] DigestMismatch(Vec, Vec), #[error("Supplied ELF image can not be run from RAM, as it includes segments mapped to ROM addresses")] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::not_ram_loadable), help("Either build the binary to be all in RAM, or remove the `--ram` option to load the image to flash") - )] + ))] ElfNotRamLoadable, #[error( "Supplied ELF image of {0}B is too big, and doesn't fit configured app partition of {1}B" )] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::image_too_big), help("Reduce the size of the binary or increase the size of the app partition."), url("https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/partition-tables.html#built-in-partition-tables") - )] + ))] ElfTooBig(u32, u32), #[error("Failed to connect to on-device flash")] - #[diagnostic(code(espflash::flash_connect))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::flash_connect)))] FlashConnect, #[error("Expected MD5 digest (16 bytes), received: {0:#x} bytes")] - #[diagnostic(code(espflash::read_flash::incorrect_digest_length))] + #[cfg_attr( + feature = "std", + diagnostic(code(espflash::read_flash::incorrect_digest_length)) + )] IncorrectDigestLength(usize), #[error("Incorrect response from the stub/ROM loader")] - #[diagnostic(code(espflash::read_flash::incorrect_response))] + #[cfg_attr( + feature = "std", + diagnostic(code(espflash::read_flash::incorrect_response)) + )] IncorrectResponse, #[error("The provided bootloader binary is invalid")] InvalidBootloader, #[error("Specified bootloader path is not a .bin file")] - #[diagnostic(code(espflash::invalid_bootloader_path))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::invalid_bootloader_path)))] InvalidBootloaderPath, #[error("The flash size '{0}' is invalid")] - #[diagnostic( - code(espflash::invalid_flash_size), - help("The accepted values are: {:?}", FlashSize::VARIANTS) + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::invalid_flash_size), + help("The accepted values are: {:?}", FlashSize::VARIANTS) + ) )] InvalidFlashSize(String), - #[cfg(not(feature = "serialport"))] - #[error(transparent)] - IoError(#[from] io::Error), - + // #[cfg(not(feature = "serialport"))] + // #[error(transparent)] + // IoError(#[from] io::Error), #[error("Specified partition table path is not a .bin or .csv file")] - #[diagnostic(code(espflash::invalid_partition_table_path))] + #[cfg_attr( + feature = "std", + diagnostic(code(espflash::invalid_partition_table_path)) + )] InvalidPartitionTablePath, #[error("No serial ports could be detected")] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::no_serial), help("Make sure you have connected a device to the host system. If the device is connected but not listed, try using the `--list-all-ports` flag.") - )] + ))] NoSerial, #[error("Read more bytes than expected")] - #[diagnostic(code(espflash::read_flash::read_more_than_expected))] + #[cfg_attr( + feature = "std", + diagnostic(code(espflash::read_flash::read_more_than_expected)) + )] ReadMoreThanExpected, #[error("This command requires using the RAM stub")] - #[diagnostic( - code(espflash::stub_required), - help("Don't use the `--no-stub` option with the command") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::stub_required), + help("Don't use the `--no-stub` option with the command") + ) )] StubRequired, #[error("The serial port '{0}' could not be found")] - #[diagnostic( - code(espflash::serial_not_found), - help("Make sure the correct device is connected to the host system") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::serial_not_found), + help("Make sure the correct device is connected to the host system") + ) )] SerialNotFound(String), #[error("The {chip} does not support {feature}")] - #[diagnostic(code(espflash::unsupported_feature))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::unsupported_feature)))] UnsupportedFeature { chip: Chip, feature: String }, #[error("Flash chip not supported, unrecognized flash ID: {0:#x}")] - #[diagnostic(code(espflash::unrecognized_flash))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::unrecognized_flash)))] UnsupportedFlash(u8), #[error("The specified flash frequency '{frequency}' is not supported by the {chip}")] - #[diagnostic(code(espflash::unsupported_flash_frequency))] + #[cfg_attr( + feature = "std", + diagnostic(code(espflash::unsupported_flash_frequency)) + )] UnsupportedFlashFrequency { chip: Chip, frequency: FlashFrequency, @@ -156,7 +196,7 @@ pub enum Error { #[error( "Minimum supported revision is {major}.{minor}, connected device's revision is {found_major}.{found_minor}" )] - #[diagnostic(code(espflash::unsupported_chip_revision))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::unsupported_chip_revision)))] UnsupportedChipRevision { major: u16, minor: u16, @@ -165,46 +205,50 @@ pub enum Error { }, #[error("Failed to parse chip revision: {chip_rev}. Chip revision must be in the format `major.minor`")] - #[diagnostic(code(espflash::cli::parse_chip_rev_error))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::cli::parse_chip_rev_error)))] ParseChipRevError { chip_rev: String }, #[error("Error while connecting to device")] - #[diagnostic(transparent)] + #[cfg_attr(feature = "std", diagnostic(transparent))] Connection(#[source] ConnectionError), #[error("Communication error while flashing device")] - #[diagnostic(transparent)] + #[cfg_attr(feature = "std", diagnostic(transparent))] Flashing(#[source] ConnectionError), #[error("Supplied ELF image is not valid")] - #[diagnostic( - code(espflash::invalid_elf), - help("Try running `cargo clean` and rebuilding the image") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::invalid_elf), + help("Try running `cargo clean` and rebuilding the image") + ) )] InvalidElf(#[from] object::Error), #[error("The bootloader returned an error")] #[cfg(feature = "serialport")] - #[diagnostic(transparent)] + #[cfg_attr(feature = "std", diagnostic(transparent))] RomError(#[from] RomError), #[cfg(feature = "cli")] #[error(transparent)] - #[diagnostic(transparent)] + #[cfg_attr(feature = "std", diagnostic(transparent))] Defmt(#[from] DefmtError), #[error("Verification of flash content failed")] - #[diagnostic(code(espflash::verify_failed))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::verify_failed)))] VerifyFailed, #[cfg(feature = "cli")] #[error(transparent)] - #[diagnostic(code(espflash::dialoguer_error))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::dialoguer_error)))] DialoguerError(#[from] dialoguer::Error), #[error(transparent)] TryFromSlice(#[from] TryFromSliceError), + #[cfg(feature = "std")] #[error("Failed to open file: {0}")] FileOpenError(String, #[source] io::Error), @@ -212,31 +256,48 @@ pub enum Error { Partition(#[from] esp_idf_part::Error), #[error("Invalid response: {0}")] - #[diagnostic(code(espflash::invalid_response))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::invalid_response)))] InvalidResponse(String), #[error("Invalid `address`({address}) and/or `size`({size}) argument(s)")] - #[diagnostic( - code(espflash::erase_region::invalid_argument), - help("`address` and `size` must be multiples of 0x1000 (4096)") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::erase_region::invalid_argument), + help("`address` and `size` must be multiples of 0x1000 (4096)") + ) )] InvalidEraseRegionArgument { address: u32, size: u32 }, #[error("The firmware was built for {elf}, but the detected chip is {detected}")] - #[diagnostic( - code(espflash::chip_mismatch), - help("Ensure that the device is connected and your host recognizes the serial adapter") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::chip_mismatch), + help( + "Ensure that the device is connected and your host recognizes the serial adapter" + ) + ) )] FirmwareChipMismatch { elf: String, detected: Chip }, #[error("The partition table does not fit into the flash ({0})")] - #[diagnostic( - code(espflash::partition_table::does_not_fit), - help("Make sure you set the correct flash size with the `--flash-size` option") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::partition_table::does_not_fit), + help("Make sure you set the correct flash size with the `--flash-size` option") + ) )] PartitionTableDoesNotFit(FlashSize), } +impl From for Error { + fn from(_: Infallible) -> Self { + unreachable!() + } +} + #[cfg(feature = "serialport")] impl From for Error { fn from(err: io::Error) -> Self { @@ -260,63 +321,72 @@ impl From for Error { } /// Connection-related errors -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] +#[cfg_attr(feature = "std", derive(Diagnostic))] #[non_exhaustive] pub enum ConnectionError { #[error("Failed to connect to the device")] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::connection_failed), help("Ensure that the device is connected and the reset and boot pins are not being held down") - )] + ))] ConnectionFailed, #[error("Serial port not found")] - #[diagnostic( - code(espflash::connection_failed), - help("Ensure that the device is connected and your host recognizes the serial adapter") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::connection_failed), + help( + "Ensure that the device is connected and your host recognizes the serial adapter" + ) + ) )] DeviceNotFound, #[error("Received packet has invalid SLIP framing")] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::slip_framing), help("Try hard-resetting the device and try again, if the error persists your ROM may be corrupted") - )] + ))] FramingError, #[error("Invalid stub handshake response received")] InvalidStubHandshake, #[error("Download mode successfully detected, but getting no sync reply")] - #[diagnostic( - code(espflash::no_sync_reply), - help("The serial TX path seems to be down") + #[cfg_attr( + feature = "std", + diagnostic( + code(espflash::no_sync_reply), + help("The serial TX path seems to be down") + ) )] NoSyncReply, #[error("Received packet to large for buffer")] - #[diagnostic( + #[cfg_attr(feature = "std", diagnostic( code(espflash::oversized_packet), help("Try hard-resetting the device and try again, if the error persists your ROM may be corrupted") - )] + ))] OverSizedPacket, #[error("Failed to read the available bytes on the serial port. Available bytes: {0}, Read bytes: {1}")] - #[diagnostic(code(espflash::read_missmatch))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::read_missmatch)))] ReadMissmatch(u32, u32), #[cfg(feature = "serialport")] #[error("Timeout while running {0}command")] - #[diagnostic(code(espflash::timeout))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::timeout)))] Timeout(TimedOutCommand), #[cfg(feature = "serialport")] #[error("IO error while using serial port: {0}")] - #[diagnostic(code(espflash::serial_error))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::serial_error)))] Serial(#[source] serialport::Error), #[error("Wrong boot mode detected ({0})! The chip needs to be in download mode.")] - #[diagnostic(code(espflash::wrong_boot_mode))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::wrong_boot_mode)))] WrongBootMode(String), } @@ -378,82 +448,83 @@ impl From for TimedOutCommand { } /// Errors originating from a device's ROM functionality -#[derive(Clone, Copy, Debug, Default, Diagnostic, Error, strum::FromRepr)] +#[derive(Clone, Copy, Debug, Default, Error, strum::FromRepr)] +#[cfg_attr(feature = "std", derive(Diagnostic))] #[non_exhaustive] #[repr(u8)] #[cfg(feature = "serialport")] pub enum RomErrorKind { #[error("Invalid message received")] - #[diagnostic(code(espflash::rom::invalid_message))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::invalid_message)))] InvalidMessage = 0x05, #[error("Bootloader failed to execute command")] - #[diagnostic(code(espflash::rom::failed))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::failed)))] FailedToAct = 0x06, #[error("Received message has invalid CRC")] - #[diagnostic(code(espflash::rom::crc))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::crc)))] InvalidCrc = 0x07, #[error("Bootloader failed to write to flash")] - #[diagnostic(code(espflash::rom::flash_write))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::flash_write)))] FlashWriteError = 0x08, #[error("Bootloader failed to read from flash")] - #[diagnostic(code(espflash::rom::flash_read))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::flash_read)))] FlashReadError = 0x09, #[error("Invalid length for flash read")] - #[diagnostic(code(espflash::rom::flash_read_length))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::flash_read_length)))] FlashReadLengthError = 0x0a, #[error("Malformed compressed data received")] - #[diagnostic(code(espflash::rom::deflate))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::deflate)))] DeflateError = 0x0b, #[error("Bad data length")] - #[diagnostic(code(espflash::rom::data_len))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::data_len)))] BadDataLen = 0xc0, #[error("Bad data checksum")] - #[diagnostic(code(espflash::rom::data_crc))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::data_crc)))] BadDataChecksum = 0xc1, #[error("Bad block size")] - #[diagnostic(code(espflash::rom::block_size))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::block_size)))] BadBlocksize = 0xc2, #[error("Invalid command")] - #[diagnostic(code(espflash::rom::cmd))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::cmd)))] InvalidCommand = 0xc3, #[error("SPI operation failed")] - #[diagnostic(code(espflash::rom::spi))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::spi)))] FailedSpiOp = 0xc4, #[error("SPI unlock failed")] - #[diagnostic(code(espflash::rom::spi_unlock))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::spi_unlock)))] FailedSpiUnlock = 0xc5, #[error("Not in flash mode")] - #[diagnostic(code(espflash::rom::flash_mode))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::flash_mode)))] NotInFlashMode = 0xc6, #[error("Error when uncompressing the data")] - #[diagnostic(code(espflash::rom::inflate))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::inflate)))] InflateError = 0xc7, #[error("Didn't receive enough data")] - #[diagnostic(code(espflash::rom::not_enough))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::not_enough)))] NotEnoughData = 0xc8, #[error("Received too much data")] - #[diagnostic(code(espflash::rom::too_much_data))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::too_much_data)))] TooMuchData = 0xc9, #[default] #[error("Other")] - #[diagnostic(code(espflash::rom::other))] + #[cfg_attr(feature = "std", diagnostic(code(espflash::rom::other)))] Other = 0xff, } @@ -465,7 +536,8 @@ impl From for RomErrorKind { } /// An error originating from a device's ROM functionality -#[derive(Clone, Copy, Debug, Diagnostic, Error)] +#[derive(Clone, Copy, Debug, Error)] +#[cfg_attr(feature = "std", derive(Diagnostic))] #[error("Error while running {command} command")] #[cfg(feature = "serialport")] #[non_exhaustive] @@ -483,11 +555,15 @@ impl RomError { } /// Missing partition error -#[derive(Debug, Diagnostic, Error)] +#[derive(Debug, Error)] +#[cfg_attr(feature = "std", derive(Diagnostic))] #[error("Missing partition")] -#[diagnostic( - code(espflash::partition_table::missing_partition), - help("Partition table must contain the partition of type `{0}` to be erased") +#[cfg_attr( + feature = "std", + diagnostic( + code(espflash::partition_table::missing_partition), + help("Partition table must contain the partition of type `{0}` to be erased") + ) )] pub struct MissingPartition(String); @@ -498,11 +574,17 @@ impl From for MissingPartition { } /// Missing partition table error -#[derive(Debug, Error, Diagnostic)] +#[derive(Debug, Error)] +#[cfg_attr(feature = "std", derive(Diagnostic))] #[error("No partition table could be found")] -#[diagnostic( - code(espflash::partition_table::missing_partition_table), - help("Try providing a CSV or binary paritition table with the `--partition-table` argument.") +#[cfg_attr( + feature = "std", + diagnostic( + code(espflash::partition_table::missing_partition_table), + help( + "Try providing a CSV or binary paritition table with the `--partition-table` argument." + ) + ) )] pub struct MissingPartitionTable; diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index 1dcee843..3224b7d3 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -6,7 +6,16 @@ #[cfg(feature = "serialport")] use std::{borrow::Cow, io::Write, path::PathBuf, thread::sleep, time::Duration}; -use std::{collections::HashMap, fmt, fs, path::Path, str::FromStr}; + +#[cfg(feature = "std")] +use std::{fs, path::Path}; + +use alloc::collections::BTreeMap; +use alloc::format; +use alloc::string::{String, ToString}; +use alloc::{vec, vec::Vec}; +use core::fmt; +use core::str::FromStr; use esp_idf_part::PartitionTable; #[cfg(feature = "serialport")] @@ -26,18 +35,14 @@ pub(crate) use self::stubs::{FLASH_SECTOR_SIZE, FLASH_WRITE_SIZE}; pub use crate::targets::flash_target::ProgressCallbacks; #[cfg(feature = "serialport")] use crate::{ + command::{Command, CommandType}, connection::{ - command::{Command, CommandType}, reset::{ResetAfterOperation, ResetBeforeOperation}, - Connection, - Port, + Connection, Port, }, error::{ConnectionError, ResultExt as _}, flasher::stubs::{ - FlashStub, - CHIP_DETECT_MAGIC_REG_ADDR, - DEFAULT_TIMEOUT, - EXPECTED_STUB_HANDSHAKE, + FlashStub, CHIP_DETECT_MAGIC_REG_ADDR, DEFAULT_TIMEOUT, EXPECTED_STUB_HANDSHAKE, }, image_format::{ram_segments, rom_segments, Segment}, }; @@ -70,8 +75,8 @@ pub struct SecurityInfo { } impl SecurityInfo { - fn security_flag_map() -> HashMap<&'static str, u32> { - HashMap::from([ + fn security_flag_map() -> BTreeMap<&'static str, u32> { + BTreeMap::from([ ("SECURE_BOOT_EN", 1 << 0), ("SECURE_BOOT_AGGRESSIVE_REVOKE", 1 << 1), ("SECURE_DOWNLOAD_ENABLE", 1 << 2), @@ -229,7 +234,19 @@ impl fmt::Display for SecurityInfo { /// Note that not all frequencies are supported by each target device. #[cfg_attr(feature = "cli", derive(clap::ValueEnum))] #[derive( - Debug, Default, Clone, Copy, Hash, PartialEq, Eq, Display, VariantNames, Serialize, Deserialize, + Debug, + Default, + Clone, + Copy, + Hash, + PartialEq, + Eq, + Display, + VariantNames, + Serialize, + Deserialize, + PartialOrd, + Ord, )] #[non_exhaustive] #[repr(u8)] @@ -479,6 +496,7 @@ pub struct FlashData { } impl FlashData { + #[cfg(feature = "std")] pub fn new( bootloader: Option<&Path>, partition_table: Option<&Path>, diff --git a/espflash/src/image_format/esp_idf.rs b/espflash/src/image_format/esp_idf.rs index a4568931..18a9ab62 100644 --- a/espflash/src/image_format/esp_idf.rs +++ b/espflash/src/image_format/esp_idf.rs @@ -1,6 +1,12 @@ //! ESP-IDF application binary image format -use std::{borrow::Cow, io::Write, iter::once, mem::size_of}; +use core::iter::once; +use core::mem::size_of; +#[cfg(not(feature = "std"))] +use embedded_io::Write; + +#[cfg(feature = "std")] +use std::io::Write; use bytemuck::{bytes_of, from_bytes, Pod, Zeroable}; use esp_idf_part::{AppType, DataType, Partition, PartitionTable, SubType, Type}; @@ -14,6 +20,11 @@ use crate::{ Error, }; +use alloc::borrow::Cow; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; + const ESP_CHECKSUM_MAGIC: u8 = 0xEF; const ESP_MAGIC: u8 = 0xE9; const IROM_ALIGN: u32 = 0x10000; @@ -336,6 +347,7 @@ impl<'a> IdfBootloaderFormat<'a> { }) } + #[cfg(feature = "std")] pub fn flash_segments<'b>(&'b self) -> Box> + 'b> where 'a: 'b, @@ -383,35 +395,38 @@ impl<'a> IdfBootloaderFormat<'a> { /// `flash_size` is used to scale app partition when present, otherwise the /// paramameter defaults are used. fn default_partition_table(params: &Esp32Params, flash_size: Option) -> PartitionTable { - PartitionTable::new(vec![ - Partition::new( - String::from("nvs"), - Type::Data, - SubType::Data(DataType::Nvs), - params.nvs_addr, - params.nvs_size, - false, - ), - Partition::new( - String::from("phy_init"), - Type::Data, - SubType::Data(DataType::Phy), - params.phy_init_data_addr, - params.phy_init_data_size, - false, - ), - Partition::new( - String::from("factory"), - Type::App, - SubType::App(AppType::Factory), - params.app_addr, - core::cmp::min( - flash_size.map_or(params.app_size, |size| size - params.app_addr), - MAX_PARTITION_SIZE, + PartitionTable::new( + [ + Partition::new( + String::from("nvs"), + Type::Data, + SubType::Data(DataType::Nvs), + params.nvs_addr, + params.nvs_size, + false, + ), + Partition::new( + String::from("phy_init"), + Type::Data, + SubType::Data(DataType::Phy), + params.phy_init_data_addr, + params.phy_init_data_size, + false, + ), + Partition::new( + String::from("factory"), + Type::App, + SubType::App(AppType::Factory), + params.app_addr, + core::cmp::min( + flash_size.map_or(params.app_size, |size| size - params.app_addr), + MAX_PARTITION_SIZE, + ), + false, ), - false, - ), - ]) + ] + .into(), + ) } /// Actual alignment (in data bytes) required for a segment header: positioned diff --git a/espflash/src/image_format/metadata.rs b/espflash/src/image_format/metadata.rs index 9eac1462..5c5b12dc 100644 --- a/espflash/src/image_format/metadata.rs +++ b/espflash/src/image_format/metadata.rs @@ -1,16 +1,20 @@ -use std::{collections::HashMap, error::Error}; +use alloc::boxed::Box; +use alloc::collections::BTreeMap; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::error::Error; use object::{File, Object, ObjectSection, ObjectSymbol}; #[derive(Debug, Clone)] pub struct Metadata { - symbols: HashMap>, + symbols: BTreeMap>, } impl Metadata { fn empty() -> Self { Self { - symbols: HashMap::new(), + symbols: BTreeMap::new(), } } @@ -60,7 +64,7 @@ impl Metadata { fn read_string<'f>(&'f self, name: &str) -> Option<&'f str> { self.symbols .get(name) - .and_then(|data| std::str::from_utf8(data).ok()) + .and_then(|data| core::str::from_utf8(data).ok()) } pub fn chip_name(&self) -> Option<&str> { diff --git a/espflash/src/image_format/mod.rs b/espflash/src/image_format/mod.rs index 54fd9c7e..337f94f9 100644 --- a/espflash/src/image_format/mod.rs +++ b/espflash/src/image_format/mod.rs @@ -1,7 +1,9 @@ //! Binary application image formats -use std::{ - borrow::Cow, +use alloc::borrow::Cow; +use alloc::boxed::Box; + +use core::{ cmp::Ordering, fmt::{Debug, Formatter}, mem::take, @@ -11,9 +13,7 @@ use std::{ use object::{ elf::SHT_PROGBITS, read::elf::{ElfFile32 as ElfFile, SectionHeader}, - Endianness, - Object as _, - ObjectSection as _, + Endianness, Object as _, ObjectSection as _, }; pub use self::{esp_idf::IdfBootloaderFormat, metadata::Metadata}; @@ -122,7 +122,7 @@ impl AddAssign<&'_ Segment<'_>> for Segment<'_> { } impl Debug for Segment<'_> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> alloc::fmt::Result { f.debug_struct("CodeSegment") .field("addr", &self.addr) .field("size", &self.size()) diff --git a/espflash/src/lib.rs b/espflash/src/lib.rs index fa54af1e..62a2e75c 100644 --- a/espflash/src/lib.rs +++ b/espflash/src/lib.rs @@ -25,7 +25,7 @@ //! //! [espflash]: https://crates.io/crates/espflash //! [cargo-binstall]: https://github.com/cargo-bins/cargo-binstall - +#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(docsrs, feature(doc_cfg))] #![deny(missing_debug_implementations, rust_2018_idioms)] @@ -34,12 +34,16 @@ pub use self::{error::Error, image_format::Segment}; #[cfg(feature = "serialport")] #[cfg_attr(docsrs, doc(cfg(feature = "serialport")))] pub mod connection; + +pub mod command; pub mod flasher; pub mod image_format; pub mod targets; mod error; +extern crate alloc; + // Command-line interface #[cfg(feature = "cli")] pub mod cli; diff --git a/espflash/src/targets/esp32.rs b/espflash/src/targets/esp32.rs index d9257a3a..02898070 100644 --- a/espflash/src/targets/esp32.rs +++ b/espflash/src/targets/esp32.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; #[cfg(feature = "serialport")] use crate::{connection::Connection, targets::bytes_to_mac_addr}; diff --git a/espflash/src/targets/esp32c2.rs b/espflash/src/targets/esp32c2.rs index d45f20f5..bcc0999b 100644 --- a/espflash/src/targets/esp32c2.rs +++ b/espflash/src/targets/esp32c2.rs @@ -1,4 +1,5 @@ -use std::{collections::HashMap, ops::Range}; +use alloc::collections::BTreeMap; +use core::ops::Range; use log::debug; @@ -81,12 +82,12 @@ impl Target for Esp32c2 { Ok(norm_xtal) } - fn flash_frequency_encodings(&self) -> HashMap { + fn flash_frequency_encodings(&self) -> BTreeMap { use FlashFrequency::*; let encodings = [(_15Mhz, 0x2), (_20Mhz, 0x1), (_30Mhz, 0x0), (_60Mhz, 0xF)]; - HashMap::from(encodings) + BTreeMap::from(encodings) } fn flash_image<'a>( diff --git a/espflash/src/targets/esp32c3.rs b/espflash/src/targets/esp32c3.rs index 450131e2..cf3cf13b 100644 --- a/espflash/src/targets/esp32c3.rs +++ b/espflash/src/targets/esp32c3.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; #[cfg(feature = "serialport")] use crate::connection::Connection; diff --git a/espflash/src/targets/esp32c6.rs b/espflash/src/targets/esp32c6.rs index a11236ee..18204d9e 100644 --- a/espflash/src/targets/esp32c6.rs +++ b/espflash/src/targets/esp32c6.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; #[cfg(feature = "serialport")] use crate::connection::Connection; diff --git a/espflash/src/targets/esp32h2.rs b/espflash/src/targets/esp32h2.rs index dd4cc3dd..29962518 100644 --- a/espflash/src/targets/esp32h2.rs +++ b/espflash/src/targets/esp32h2.rs @@ -1,4 +1,5 @@ -use std::{collections::HashMap, ops::Range}; +use alloc::collections::BTreeMap; +use core::ops::Range; #[cfg(feature = "serialport")] use crate::connection::Connection; @@ -71,12 +72,12 @@ impl Target for Esp32h2 { Ok(XtalFrequency::_32Mhz) } - fn flash_frequency_encodings(&self) -> HashMap { + fn flash_frequency_encodings(&self) -> BTreeMap { use FlashFrequency::*; let encodings = [(_12Mhz, 0x2), (_16Mhz, 0x1), (_24Mhz, 0x0), (_48Mhz, 0xF)]; - HashMap::from(encodings) + BTreeMap::from(encodings) } fn flash_image<'a>( diff --git a/espflash/src/targets/esp32p4.rs b/espflash/src/targets/esp32p4.rs index b0fc11c1..92040d77 100644 --- a/espflash/src/targets/esp32p4.rs +++ b/espflash/src/targets/esp32p4.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; #[cfg(feature = "serialport")] use crate::connection::Connection; diff --git a/espflash/src/targets/esp32s2.rs b/espflash/src/targets/esp32s2.rs index cde2491a..d4dcaa23 100644 --- a/espflash/src/targets/esp32s2.rs +++ b/espflash/src/targets/esp32s2.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; #[cfg(feature = "serialport")] use super::flash_target::MAX_RAM_BLOCK_SIZE; diff --git a/espflash/src/targets/esp32s3.rs b/espflash/src/targets/esp32s3.rs index d8daae5c..b5f2ce14 100644 --- a/espflash/src/targets/esp32s3.rs +++ b/espflash/src/targets/esp32s3.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; #[cfg(feature = "serialport")] use crate::connection::Connection; diff --git a/espflash/src/targets/flash_target/esp32.rs b/espflash/src/targets/flash_target/esp32.rs index 9a24e054..123b4fa0 100644 --- a/espflash/src/targets/flash_target/esp32.rs +++ b/espflash/src/targets/flash_target/esp32.rs @@ -9,10 +9,8 @@ use md5::{Digest, Md5}; #[cfg(feature = "serialport")] use crate::{ - connection::{ - command::{Command, CommandType}, - Connection, - }, + command::{Command, CommandType}, + connection::Connection, flasher::ProgressCallbacks, targets::FlashTarget, }; diff --git a/espflash/src/targets/flash_target/ram.rs b/espflash/src/targets/flash_target/ram.rs index ffee6441..faf3b124 100644 --- a/espflash/src/targets/flash_target/ram.rs +++ b/espflash/src/targets/flash_target/ram.rs @@ -1,9 +1,7 @@ #[cfg(feature = "serialport")] use crate::{ - connection::{ - command::{Command, CommandType}, - Connection, - }, + command::{Command, CommandType}, + connection::Connection, flasher::ProgressCallbacks, targets::FlashTarget, }; diff --git a/espflash/src/targets/mod.rs b/espflash/src/targets/mod.rs index b009ff82..667ff256 100644 --- a/espflash/src/targets/mod.rs +++ b/espflash/src/targets/mod.rs @@ -4,7 +4,9 @@ //! possible to write an application to and boot from RAM, where a bootloader is //! obviously not required either. -use std::collections::HashMap; +use alloc::boxed::Box; +use alloc::collections::BTreeMap; +use alloc::format; use serde::{Deserialize, Serialize}; use strum::{Display, EnumIter, EnumString, VariantNames}; @@ -21,14 +23,8 @@ use crate::{ flasher::{FlashData, FlashFrequency}, image_format::IdfBootloaderFormat, targets::{ - esp32::Esp32, - esp32c2::Esp32c2, - esp32c3::Esp32c3, - esp32c6::Esp32c6, - esp32h2::Esp32h2, - esp32p4::Esp32p4, - esp32s2::Esp32s2, - esp32s3::Esp32s3, + esp32::Esp32, esp32c2::Esp32c2, esp32c3::Esp32c3, esp32c6::Esp32c6, esp32h2::Esp32h2, + esp32p4::Esp32p4, esp32s2::Esp32s2, esp32s3::Esp32s3, }, Error, }; @@ -337,12 +333,12 @@ pub trait Target: ReadEFuse { fn crystal_freq(&self, connection: &mut Connection) -> Result; /// Numeric encodings for the flash frequencies supported by a chip - fn flash_frequency_encodings(&self) -> HashMap { + fn flash_frequency_encodings(&self) -> BTreeMap { use FlashFrequency::*; let encodings = [(_20Mhz, 0x2), (_26Mhz, 0x1), (_40Mhz, 0x0), (_80Mhz, 0xf)]; - HashMap::from(encodings) + BTreeMap::from(encodings) } #[cfg(feature = "serialport")] From d6f7bcb19057aa13d800bb84f51bf0253aa1ac1e Mon Sep 17 00:00:00 2001 From: ferris Date: Mon, 7 Apr 2025 00:24:26 +0200 Subject: [PATCH 2/6] Use git instead of path --- Cargo.lock | 1 + espflash/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c8cd3fe1..03184c5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1225,6 +1225,7 @@ dependencies = [ [[package]] name = "esp-idf-part" version = "0.5.0" +source = "git+https://github.com/i404788/esp-idf-part.git#094ab03c1e99281e8de4e3e45dc5374b5ad89445" dependencies = [ "csv", "deku", diff --git a/espflash/Cargo.toml b/espflash/Cargo.toml index 0b00ceb2..f10efc33 100644 --- a/espflash/Cargo.toml +++ b/espflash/Cargo.toml @@ -38,7 +38,7 @@ defmt-decoder = { version = "=0.4.0", features = ["unstable"], optional = true dialoguer = { version = "0.11.0", optional = true } directories = { version = "5.0.1", optional = true } env_logger = { version = "0.11.6", optional = true } -esp-idf-part = { path = "../../esp-idf-part", default-features = false } +esp-idf-part = { git = "https://github.com/i404788/esp-idf-part.git", default-features = false } flate2 = { version = "1.0.35", optional = true } indicatif = { version = "0.17.9", optional = true } log = "0.4.22" From a45c90986cecbca046b1665659f16e4f1bfb45e3 Mon Sep 17 00:00:00 2001 From: ferris Date: Mon, 7 Apr 2025 09:48:00 +0200 Subject: [PATCH 3/6] Make SlipEncoder/SlipDecoder embedded-io compatible --- espflash/src/connection/mod.rs | 306 +++++++++++++++++++++++++++++++-- espflash/src/error.rs | 31 +++- 2 files changed, 318 insertions(+), 19 deletions(-) diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index 006033b0..c97be745 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -6,22 +6,23 @@ #[cfg(feature = "std")] use std::{ - io::{BufWriter, Read, Write}, + io::{BufWriter, Read, Write as _}, thread::sleep, }; use core::iter::zip; use core::time::Duration; +use embedded_io::Write; use log::{debug, info}; use regex::Regex; use serialport::{SerialPort, UsbPortInfo}; -use slip_codec::SlipDecoder; #[cfg(unix)] use self::reset::UnixTightReset; -use self::{ +pub use self::{ command::{Command, CommandType}, + decoder::{SlipDecoder, SlipError}, encoder::SlipEncoder, reset::{ construct_reset_strategy_sequence, hard_reset, reset_after_flash, soft_reset, ClassicReset, @@ -406,7 +407,8 @@ impl Connection { pub fn read_flash_response(&mut self) -> Result, Error> { let mut response = Vec::new(); - self.decoder.decode(&mut self.serial, &mut response)?; + let mut reader = embedded_io_adapters::std::FromStd::new(&mut self.serial); + self.decoder.decode(&mut reader, &mut response)?; if response.is_empty() { return Ok(None); @@ -492,7 +494,7 @@ impl Connection { let mut binding = Box::new(&mut self.serial); let serial = binding.as_mut(); serial.clear(serialport::ClearBuffer::Input)?; - let mut writer = BufWriter::new(serial); + let mut writer = embedded_io_adapters::std::FromStd::new(BufWriter::new(serial)); let mut encoder = SlipEncoder::new(&mut writer)?; encoder.write_all(&data.to_le_bytes())?; encoder.finish()?; @@ -507,10 +509,10 @@ impl Connection { let serial = binding.as_mut(); serial.clear(serialport::ClearBuffer::Input)?; - let mut writer = BufWriter::new(serial); - let mut encoder = embedded_io_adapters::std::FromStd::new(SlipEncoder::new(&mut writer)?); + let mut writer = embedded_io_adapters::std::FromStd::new(BufWriter::new(serial)); + let mut encoder = SlipEncoder::new(&mut writer)?; command.write(&mut encoder)?; - encoder.into_inner().finish()?; + encoder.finish()?; writer.flush()?; Ok(()) } @@ -574,7 +576,8 @@ impl Connection { pub(crate) fn read(&mut self, len: usize) -> Result>, Error> { let mut tmp = Vec::with_capacity(1024); loop { - self.decoder.decode(&mut self.serial, &mut tmp)?; + let mut reader = embedded_io_adapters::std::FromStd::new(&mut self.serial); + self.decoder.decode(&mut reader, &mut tmp)?; if tmp.len() >= len { return Ok(Some(tmp)); } @@ -603,13 +606,15 @@ impl Connection { } mod encoder { - use super::Write; + use core::fmt::Debug; + use embedded_io::Write; const END: u8 = 0xC0; const ESC: u8 = 0xDB; const ESC_END: u8 = 0xDC; const ESC_ESC: u8 = 0xDD; + #[derive(Debug)] pub struct SlipEncoder<'a, W: Write> { writer: &'a mut W, len: usize, @@ -617,22 +622,26 @@ mod encoder { impl<'a, W: Write> SlipEncoder<'a, W> { /// Creates a new encoder context - pub fn new(writer: &'a mut W) -> std::io::Result { + pub fn new(writer: &'a mut W) -> Result { let len = writer.write(&[END])?; Ok(Self { writer, len }) } - pub fn finish(mut self) -> std::io::Result { + pub fn finish(mut self) -> Result { self.len += self.writer.write(&[END])?; Ok(self.len) } } + impl embedded_io::ErrorType for SlipEncoder<'_, W> { + type Error = W::Error; + } + impl Write for SlipEncoder<'_, W> { /// Writes the given buffer replacing the END and ESC bytes /// /// See https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/serial-protocol.html#low-level-protocol - fn write(&mut self, buf: &[u8]) -> std::io::Result { + fn write(&mut self, buf: &[u8]) -> Result { for value in buf.iter() { match *value { END => { @@ -650,8 +659,277 @@ mod encoder { Ok(buf.len()) } - fn flush(&mut self) -> std::io::Result<()> { + fn flush(&mut self) -> Result<(), W::Error> { self.writer.flush() } } } + +mod decoder { + /// SLIP end of packet token + const END: u8 = 0xC0; + + /// SLIP escape token + const ESC: u8 = 0xDB; + + /// SLIP escaped 0xC0 token + const ESC_END: u8 = 0xDC; + + /// SLIP escaped 0xDB token + const ESC_ESC: u8 = 0xDD; + + /// Recommended maximum SLIP packet size per RFC 1055 + #[allow(dead_code)] + const MAX_PACKET_SIZE: usize = 1006; + use core::convert::Infallible; + use embedded_io::{Read, Write}; + + /// SLIP decoder error type + #[derive(Debug)] + pub enum SlipError { + FramingError, + OversizedPacket, + EndOfStream, + ReadError(RE), + WriteError(WE), + } + + pub type SlipResult = std::result::Result>; + + #[derive(Debug)] + enum State { + Normal, + Error, + Escape, + } + + /// SLIP decoder context + #[derive(Debug)] + pub struct SlipDecoder { + count: usize, + state: State, + } + + // Unfortunately even the never type doesn't auto-coerce + fn coerce_infallible(err: SlipError) -> SlipError { + match err { + SlipError::ReadError(_) => { + unreachable!() + } + SlipError::WriteError(e) => SlipError::WriteError(e), + SlipError::FramingError => SlipError::FramingError, + SlipError::OversizedPacket => SlipError::OversizedPacket, + SlipError::EndOfStream => SlipError::EndOfStream, + } + } + + impl SlipDecoder { + /// Creates a new context with the given maximum buffer size. + pub fn new() -> Self { + Self { + count: 0usize, + state: State::Normal, + } + } + + fn push( + &mut self, + sink: &mut W, + value: u8, + ) -> self::SlipResult { + match sink.write(&[value]) { + Ok(len) => { + if len != 1 { + Err(SlipError::OversizedPacket) + } else { + self.count += 1; + Ok(1usize) + } + } + Err(error) => Err(SlipError::WriteError(error)), + } + } + + /// Attempts to decode a single SLIP frame from the given source. + /// + /// # Arguments + /// + /// * `source` - Encoded SLIP data source implementing the std::io::Read + /// trait + /// + /// Returns a Vec containing a decoded message or an empty Vec if + /// of the source data was reached. + /// + pub fn decode( + &mut self, + source: &mut R, + sink: &mut W, + ) -> self::SlipResult { + loop { + let mut buf = [0u8; 16]; + let read_amount = source.read(&mut buf).map_err(SlipError::ReadError)?; + + for value in buf[0..read_amount].iter().cloned() { + match self.state { + State::Normal => match value { + END => { + if self.count > 0 { + let len = self.count; + + self.count = 0usize; + + return Ok(len); + } + } + ESC => { + self.state = State::Escape; + } + _ => { + self.push(sink, value).map_err(coerce_infallible)?; + } + }, + State::Error => { + if value == END { + self.count = 0usize; + self.state = State::Normal; + } + } + State::Escape => match value { + ESC_END => { + self.push(sink, END).map_err(coerce_infallible)?; + self.state = State::Normal; + } + ESC_ESC => { + self.push(sink, ESC).map_err(coerce_infallible)?; + self.state = State::Normal; + } + _ => { + self.state = State::Error; + + return Err(SlipError::FramingError); + } + }, + } + } + + if read_amount < buf.len() { + Err(SlipError::EndOfStream)? + } + } + } + } + + impl Default for SlipDecoder { + fn default() -> Self { + Self::new() + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn empty_decode() { + const INPUT: [u8; 2] = [0xc0, 0xc0]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + let res = slip.decode(&mut INPUT.as_ref(), &mut buf); + assert!(res.is_err()); + assert!(buf.is_empty()); + } + + #[test] + fn simple_decode() { + const INPUT: [u8; 7] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0]; + const DATA: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05]; + + let mut slip = SlipDecoder::new(); + let mut buf = [0u8; DATA.len()]; + let len = slip.decode(&mut INPUT.as_ref(), &mut buf.as_mut()).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, &buf); + } + + /// Ensure that [ESC, ESC_END] -> [END] + #[test] + fn decode_esc_then_esc_end_sequence() { + const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdc, 0x03, 0xc0]; + const DATA: [u8; 3] = [0x01, 0xc0, 0x03]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, buf.as_slice()); + } + + /// Ensure that [ESC, ESC_ESC] -> [ESC] + #[test] + fn decode_esc_then_esc_esc_sequence() { + const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdd, 0x03, 0xc0]; + const DATA: [u8; 3] = [0x01, 0xdb, 0x03]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, buf.as_slice()); + } + + #[test] + fn multi_part_decode() { + const INPUT_1: [u8; 6] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05]; + const INPUT_2: [u8; 6] = [0x05, 0x06, 0x07, 0x08, 0x09, 0xc0]; + const DATA: [u8; 10] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + + { + let res = slip.decode(&mut INPUT_1.as_ref(), &mut buf); + assert!(res.is_err()); + assert_eq!(5, buf.len()); + } + + { + let len = slip.decode(&mut INPUT_2.as_ref(), &mut buf).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, buf.as_slice()); + } + } + + #[test] + fn compound_decode() { + const INPUT: [u8; 13] = [ + 0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0, 0x05, 0x06, 0x07, 0x08, 0x09, 0xc0, + ]; + const DATA_1: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05]; + const DATA_2: [u8; 5] = [0x05, 0x06, 0x07, 0x08, 0x09]; + + let mut slip = SlipDecoder::new(); + let reader = &mut INPUT.as_ref(); + + { + let mut buf: Vec = Vec::new(); + let len = slip.decode(reader, &mut buf).unwrap(); + assert_eq!(DATA_1.len(), len); + assert_eq!(DATA_1.len(), buf.len()); + assert_eq!(&DATA_1, buf.as_slice()); + } + + { + let mut buf: Vec = Vec::new(); + let len = slip.decode(reader, &mut buf).unwrap(); + assert_eq!(DATA_2.len(), len); + assert_eq!(DATA_2.len(), buf.len()); + assert_eq!(&DATA_2, buf.as_slice()); + } + } + } +} diff --git a/espflash/src/error.rs b/espflash/src/error.rs index f5a81366..7bf7f378 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -13,7 +13,7 @@ use std::io; use miette::Diagnostic; #[cfg(feature = "serialport")] -use slip_codec::SlipError; +use crate::connection::SlipError; use strum::VariantNames; use thiserror::Error; @@ -314,8 +314,15 @@ impl From for Error { } #[cfg(feature = "serialport")] -impl From for Error { - fn from(err: SlipError) -> Self { +impl From> for Error { + fn from(err: SlipError) -> Self { + Self::Connection(err.into()) + } +} + +#[cfg(feature = "serialport")] +impl From> for Error { + fn from(err: SlipError) -> Self { Self::Connection(err.into()) } } @@ -412,12 +419,26 @@ impl From for ConnectionError { } #[cfg(feature = "serialport")] -impl From for ConnectionError { - fn from(err: SlipError) -> Self { +impl From> for ConnectionError { + fn from(err: SlipError) -> Self { + match err { + SlipError::FramingError => Self::FramingError, + SlipError::OversizedPacket => Self::OverSizedPacket, + SlipError::ReadError(io) => Self::from(io), + SlipError::WriteError(io) => Self::from(io), + SlipError::EndOfStream => Self::FramingError, + } + } +} + +#[cfg(feature = "serialport")] +impl From> for ConnectionError { + fn from(err: SlipError) -> Self { match err { SlipError::FramingError => Self::FramingError, SlipError::OversizedPacket => Self::OverSizedPacket, SlipError::ReadError(io) => Self::from(io), + SlipError::WriteError(_) => unreachable!(), SlipError::EndOfStream => Self::FramingError, } } From bacd4f3b8aa81f5700eaaa378154c637e4b845d0 Mon Sep 17 00:00:00 2001 From: ferris Date: Mon, 7 Apr 2025 14:57:10 +0200 Subject: [PATCH 4/6] Remove serde from no_std --- Cargo.lock | 8 ++-- espflash/Cargo.toml | 4 +- espflash/src/flasher/mod.rs | 86 +++++++++++++++---------------------- espflash/src/targets/mod.rs | 6 +-- 4 files changed, 43 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03184c5c..7c6257d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3918,9 +3918,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] @@ -3948,9 +3948,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", diff --git a/espflash/Cargo.toml b/espflash/Cargo.toml index f10efc33..80ffa09c 100644 --- a/espflash/Cargo.toml +++ b/espflash/Cargo.toml @@ -46,7 +46,7 @@ md-5 = { version = "0.10.6", default-features = false} miette = { version = "7.4.0", optional = true} object = { version = "0.36.7", default-features = false, features = ['read'] } regex = { version = "1.11.1", optional = true } -serde = { version = "1.0.217", features = ["derive"], default-features = false } +serde = { version = "1.0.219", features = ["derive"], optional = true } serialport = { version = "4.7.0", default-features = false, optional = true } sha2 = { version = "0.10.8", default-features = false} slip-codec = { version = "0.4.0", optional = true } @@ -85,4 +85,4 @@ cli = [ # Enables connecting to a device via serial port serialport = ["dep:regex", "dep:serialport", "dep:slip-codec", "dep:toml", "std"] -std = ["dep:miette", "dep:flate2", "object/default", "serde/std", "thiserror/std", "strum/std", "esp-idf-part/std", "md-5/std", "sha2/std", "base64/std", "embedded-io/std", "embedded-io-adapters/std"] +std = ["dep:miette", "dep:flate2", "object/default", "dep:serde", "thiserror/std", "strum/std", "esp-idf-part/std", "md-5/std", "sha2/std", "base64/std", "embedded-io/std", "embedded-io-adapters/std"] diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index 3224b7d3..8ef4d090 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -24,6 +24,8 @@ use log::{debug, info, warn}; use md5::{Digest, Md5}; #[cfg(feature = "serialport")] use object::{read::elf::ElfFile32 as ElfFile, Endianness}; + +#[cfg(feature = "std")] use serde::{Deserialize, Serialize}; #[cfg(feature = "serialport")] use serialport::UsbPortInfo; @@ -233,57 +235,46 @@ impl fmt::Display for SecurityInfo { /// /// Note that not all frequencies are supported by each target device. #[cfg_attr(feature = "cli", derive(clap::ValueEnum))] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive( - Debug, - Default, - Clone, - Copy, - Hash, - PartialEq, - Eq, - Display, - VariantNames, - Serialize, - Deserialize, - PartialOrd, - Ord, + Debug, Default, Clone, Copy, Hash, PartialEq, Eq, Display, VariantNames, PartialOrd, Ord, )] #[non_exhaustive] #[repr(u8)] pub enum FlashFrequency { /// 12 MHz - #[serde(rename = "12MHz")] + #[cfg_attr(feature = "std", serde(rename = "12MHz"))] _12Mhz, /// 15 MHz - #[serde(rename = "15MHz")] + #[cfg_attr(feature = "std", serde(rename = "15MHz"))] _15Mhz, /// 16 MHz - #[serde(rename = "16MHz")] + #[cfg_attr(feature = "std", serde(rename = "16MHz"))] _16Mhz, /// 20 MHz - #[serde(rename = "20MHz")] + #[cfg_attr(feature = "std", serde(rename = "20MHz"))] _20Mhz, /// 24 MHz - #[serde(rename = "24MHz")] + #[cfg_attr(feature = "std", serde(rename = "24MHz"))] _24Mhz, /// 26 MHz - #[serde(rename = "26MHz")] + #[cfg_attr(feature = "std", serde(rename = "26MHz"))] _26Mhz, /// 30 MHz - #[serde(rename = "30MHz")] + #[cfg_attr(feature = "std", serde(rename = "30MHz"))] _30Mhz, /// 40 MHz - #[serde(rename = "40MHz")] + #[cfg_attr(feature = "std", serde(rename = "40MHz"))] #[default] _40Mhz, /// 48 MHz - #[serde(rename = "48MHz")] + #[cfg_attr(feature = "std", serde(rename = "48MHz"))] _48Mhz, /// 60 MHz - #[serde(rename = "60MHz")] + #[cfg_attr(feature = "std", serde(rename = "60MHz"))] _60Mhz, /// 80 MHz - #[serde(rename = "80MHz")] + #[cfg_attr(feature = "std", serde(rename = "80MHz"))] _80Mhz, } @@ -304,10 +295,11 @@ impl FlashFrequency { /// Supported flash modes #[cfg_attr(feature = "cli", derive(clap::ValueEnum))] -#[derive(Copy, Clone, Debug, Default, VariantNames, Serialize, Deserialize)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Copy, Clone, Debug, Default, VariantNames)] #[non_exhaustive] #[strum(serialize_all = "lowercase")] -#[serde(rename_all = "lowercase")] +#[cfg_attr(feature = "std", serde(rename_all = "lowercase"))] pub enum FlashMode { /// Quad I/O (4 pins used for address & data) Qio, @@ -324,57 +316,46 @@ pub enum FlashMode { /// /// Note that not all sizes are supported by each target device. #[cfg_attr(feature = "cli", derive(clap::ValueEnum))] -#[derive( - Clone, - Copy, - Debug, - Default, - Eq, - PartialEq, - Display, - VariantNames, - EnumIter, - Serialize, - Deserialize, -)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Display, VariantNames, EnumIter)] #[non_exhaustive] #[repr(u8)] #[strum(serialize_all = "SCREAMING_SNAKE_CASE")] #[doc(alias("esp_image_flash_size_t"))] pub enum FlashSize { /// 256 KB - #[serde(rename = "256KB")] + #[cfg_attr(feature = "std", serde(rename = "256KB"))] _256Kb, /// 512 KB - #[serde(rename = "512KB")] + #[cfg_attr(feature = "std", serde(rename = "512KB"))] _512Kb, /// 1 MB - #[serde(rename = "1MB")] + #[cfg_attr(feature = "std", serde(rename = "1MB"))] _1Mb, /// 2 MB - #[serde(rename = "2MB")] + #[cfg_attr(feature = "std", serde(rename = "2MB"))] _2Mb, /// 4 MB #[default] - #[serde(rename = "4MB")] + #[cfg_attr(feature = "std", serde(rename = "4MB"))] _4Mb, /// 8 MB - #[serde(rename = "8MB")] + #[cfg_attr(feature = "std", serde(rename = "8MB"))] _8Mb, /// 16 MB - #[serde(rename = "16MB")] + #[cfg_attr(feature = "std", serde(rename = "16MB"))] _16Mb, /// 32 MB - #[serde(rename = "32MB")] + #[cfg_attr(feature = "std", serde(rename = "32MB"))] _32Mb, /// 64 MB - #[serde(rename = "64MB")] + #[cfg_attr(feature = "std", serde(rename = "64MB"))] _64Mb, /// 128 MB - #[serde(rename = "128MB")] + #[cfg_attr(feature = "std", serde(rename = "128MB"))] _128Mb, /// 256 MB - #[serde(rename = "256MB")] + #[cfg_attr(feature = "std", serde(rename = "256MB"))] _256Mb, } @@ -456,12 +437,13 @@ impl FromStr for FlashSize { } /// Flash settings to use when flashing a device -#[derive(Copy, Clone, Debug, Serialize, Deserialize, Default)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Copy, Clone, Debug, Default)] #[non_exhaustive] pub struct FlashSettings { pub mode: Option, pub size: Option, - #[serde(rename = "frequency")] + #[cfg_attr(feature = "std", serde(rename = "frequency"))] pub freq: Option, } diff --git a/espflash/src/targets/mod.rs b/espflash/src/targets/mod.rs index 667ff256..23a85f9c 100644 --- a/espflash/src/targets/mod.rs +++ b/espflash/src/targets/mod.rs @@ -8,6 +8,7 @@ use alloc::boxed::Box; use alloc::collections::BTreeMap; use alloc::format; +#[cfg(feature = "std")] use serde::{Deserialize, Serialize}; use strum::{Display, EnumIter, EnumString, VariantNames}; @@ -45,9 +46,8 @@ pub(crate) mod flash_target; /// /// Note that not all frequencies are supported by each target device. #[cfg_attr(feature = "cli", derive(clap::ValueEnum))] -#[derive( - Debug, Default, Clone, Copy, Hash, PartialEq, Eq, Display, VariantNames, Serialize, Deserialize, -)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize,))] +#[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, Display, VariantNames)] #[non_exhaustive] #[repr(u32)] pub enum XtalFrequency { From 6c00f8ad69a306b0bf446c8a94218a60a1ea42f3 Mon Sep 17 00:00:00 2001 From: ferris Date: Mon, 7 Apr 2025 15:26:31 +0200 Subject: [PATCH 5/6] Fix errors --- Cargo.lock | 1006 ++++++++++++++++++------------ espflash/src/connection/mod.rs | 343 +--------- espflash/src/connection/reset.rs | 8 +- espflash/src/error.rs | 3 +- espflash/src/lib.rs | 1 + espflash/src/slip.rs | 328 ++++++++++ 6 files changed, 936 insertions(+), 753 deletions(-) create mode 100644 espflash/src/slip.rs diff --git a/Cargo.lock b/Cargo.lock index 7c6257d6..bae01a8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,7 +33,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -113,19 +113,20 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "arc-swap" @@ -189,9 +190,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bitflags" @@ -228,9 +229,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.5" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" +checksum = "389a099b34312839e16420d499a9cad9650541715937ffbdd40d36f49e77eeb3" dependencies = [ "arrayref", "arrayvec", @@ -261,24 +262,24 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytemuck" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.8.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" dependencies = [ "proc-macro2", "quote", @@ -293,15 +294,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytesize" -version = "1.3.0" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" +checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] name = "camino" @@ -363,7 +364,7 @@ dependencies = [ "os_info", "pasetors", "pathdiff", - "rand", + "rand 0.8.5", "regex", "rusqlite", "rustc-hash", @@ -412,9 +413,9 @@ dependencies = [ [[package]] name = "cargo-credential-libsecret" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076ddcb7c59457842cd392006f4b07ab3e3dbc430aac1114a6fc1db5501ae7fa" +checksum = "e8d8dbc26ce815b430803e756f6ad5f70a67d47bfcde9ca6f4276732c39551b8" dependencies = [ "anyhow", "cargo-credential", @@ -423,9 +424,9 @@ dependencies = [ [[package]] name = "cargo-credential-macos-keychain" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421c4abb9c2d9786b7719b7020c8cc9518d82e86a0e397127dbe941a7d2c6e13" +checksum = "b489cbdae63be32c040b5fe81b0f7725e563bcd805bb828e746971a4967aaf28" dependencies = [ "cargo-credential", "security-framework", @@ -433,9 +434,9 @@ dependencies = [ [[package]] name = "cargo-credential-wincred" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a898056d56c314649dfeec5b7d8498440baaee54c9462684f72be6448d961382" +checksum = "49c6cb2255a5267a4d18077bc436db5a2c261d97a3dcbc84ccd9747b473b2f4b" dependencies = [ "cargo-credential", "windows-sys 0.59.0", @@ -452,7 +453,7 @@ dependencies = [ "log", "miette", "serde", - "thiserror 2.0.10", + "thiserror 2.0.12", "toml", ] @@ -476,9 +477,9 @@ dependencies = [ [[package]] name = "cargo-util" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cccd15f96a29696e13e1d5fa10dd1dbed2e172f58b6e6124a9a4fa695363fdd" +checksum = "527f6e2a4e80492e90628052be879a5996c2453ad5ec745bfa310a80b7eca20a" dependencies = [ "anyhow", "core-foundation", @@ -499,9 +500,9 @@ dependencies = [ [[package]] name = "cargo-util-schemas" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a31f1bb58068aa01b7809533b02c26b1e64a7810ae99131da5af1a4b8e7fc2" +checksum = "9f905f68f8cb8a8182592d9858a5895360f0a5b08b6901fdb10498fb91829804" dependencies = [ "semver", "serde", @@ -515,23 +516,23 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.19.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8769706aad5d996120af43197bf46ef6ad0fda35216b4505f926a365a232d924" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", "cargo-platform 0.1.9", "semver", "serde", "serde_json", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "cc" -version = "1.2.7" +version = "1.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +checksum = "525046617d8376e3db1deffb079e91cef90a89fc3ca5c185bbf8c9ecdd15cd5c" dependencies = [ "jobserver", "libc", @@ -552,9 +553,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "clap" -version = "4.5.26" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" dependencies = [ "clap_builder", "clap_derive", @@ -562,9 +563,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.26" +version = "4.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" dependencies = [ "anstream", "anstyle", @@ -575,9 +576,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.42" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a7e468e750fa4b6be660e8b5651ad47372e8fb114030b594c2d75d48c5ffd0" +checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6" dependencies = [ "clap", "clap_lex", @@ -587,9 +588,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -648,21 +649,20 @@ dependencies = [ [[package]] name = "comfy-table" -version = "7.1.3" +version = "7.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24f165e7b643266ea80cb858aed492ad9280e3e05ce24d4a99d7d7b889b6a4d9" +checksum = "4a65ebfec4fb190b6f90e944a817d60499ee0744e582530e2c9900a22e591d9a" dependencies = [ "crossterm", - "strum", - "strum_macros", + "unicode-segmentation", "unicode-width 0.2.0", ] [[package]] name = "console" -version = "0.15.10" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", "libc", @@ -710,24 +710,24 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crates-io" -version = "0.40.7" +version = "0.40.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c5329bd312e7a49d5fb3f4a8f705212dc4160e2be75433b1ae26d602aeb889" +checksum = "6967b9fa81bc485cf87748fdc2f8c79b922f5c59fe4f7c160329cee7fae4a314" dependencies = [ "curl", "percent-encoding", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.12", "url", ] @@ -784,7 +784,7 @@ dependencies = [ "crossterm_winapi", "mio", "parking_lot", - "rustix", + "rustix 0.38.44", "signal-hook", "signal-hook-mio", "winapi", @@ -806,7 +806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -835,9 +835,9 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" dependencies = [ "memchr", ] @@ -850,9 +850,9 @@ checksum = "b916ba8ce9e4182696896f015e8a5ae6081b305f74690baa8465e35f5a142ea4" [[package]] name = "ctrlc" -version = "3.4.5" +version = "3.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +checksum = "697b5419f348fd5ae2478e8018cb016c00a5881c7f46c717de98ffd135a5651c" dependencies = [ "nix 0.29.0", "windows-sys 0.59.0", @@ -875,9 +875,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.78+curl-8.11.0" +version = "0.4.80+curl-8.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eec768341c5c7789611ae51cf6c459099f22e64a5d5d0ce4892434e33821eaf" +checksum = "55f7df2eac63200c3ab25bde3b2268ef2ee56af3d238e76d61f01c3c49bff734" dependencies = [ "cc", "libc", @@ -975,7 +975,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" dependencies = [ - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1016,9 +1016,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", "serde", @@ -1083,9 +1083,9 @@ dependencies = [ [[package]] name = "dissimilar" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" +checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" [[package]] name = "dunce" @@ -1113,14 +1113,14 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" @@ -1137,7 +1137,7 @@ dependencies = [ "hkdf", "pem-rfc7468", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -1185,28 +1185,28 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" dependencies = [ "serde", "typeid", @@ -1214,9 +1214,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1225,7 +1225,7 @@ dependencies = [ [[package]] name = "esp-idf-part" version = "0.5.0" -source = "git+https://github.com/i404788/esp-idf-part.git#094ab03c1e99281e8de4e3e45dc5374b5ad89445" +source = "git+https://github.com/i404788/esp-idf-part.git#bc98aaf674318f3f1514a5a1a75721cae6fcc50f" dependencies = [ "csv", "deku", @@ -1233,9 +1233,8 @@ dependencies = [ "parse_int", "regex", "serde", - "serde_plain", "strum", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1272,7 +1271,7 @@ dependencies = [ "sha2", "slip-codec", "strum", - "thiserror 2.0.10", + "thiserror 2.0.12", "toml", "update-informer", ] @@ -1317,11 +1316,11 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "ff" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1345,9 +1344,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "libz-sys", @@ -1460,7 +1459,21 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", "wasm-bindgen", ] @@ -1562,21 +1575,21 @@ dependencies = [ "once_cell", "prodash", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "gix-actor" -version = "0.33.1" +version = "0.33.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b24171f514cef7bb4dfb72a0b06dacf609b33ba8ad2489d4c4559a03b7afb3" +checksum = "20018a1a6332e065f1fcc8305c1c932c6b8c9985edea2284b3c79dc6fa3ee4b2" dependencies = [ "bstr", "gix-date", "gix-utils", "itoa", - "thiserror 2.0.10", - "winnow", + "thiserror 2.0.12", + "winnow 0.6.26", ] [[package]] @@ -1592,26 +1605,26 @@ dependencies = [ "gix-trace", "kstring", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", "unicode-bom", ] [[package]] name = "gix-bitmap" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48b897b4bbc881aea994b4a5bbb340a04979d7be9089791304e04a9fbc66b53" +checksum = "b1db9765c69502650da68f0804e3dc2b5f8ccc6a2d104ca6c85bc40700d37540" dependencies = [ - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "gix-chunk" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ffbeb3a5c0b8b84c3fe4133a6f8c82fa962f4caefe8d0762eced025d3eb4f7" +checksum = "0b1f1d8764958699dc764e3f727cef280ff4d1bd92c107bbf8acd85b30c1bd6f" dependencies = [ - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1637,7 +1650,7 @@ dependencies = [ "gix-features", "gix-hash", "memmap2", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1656,22 +1669,22 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", "unicode-bom", - "winnow", + "winnow 0.6.26", ] [[package]] name = "gix-config-value" -version = "0.14.11" +version = "0.14.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11365144ef93082f3403471dbaa94cfe4b5e72743bdb9560719a251d439f4cee" +checksum = "8dc2c844c4cf141884678cabef736fd91dd73068b9146e6f004ba1a0457944b6" dependencies = [ "bitflags 2.9.0", "bstr", "gix-path", "libc", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1688,19 +1701,19 @@ dependencies = [ "gix-sec", "gix-trace", "gix-url", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "gix-date" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c57c477b645ee248b173bb1176b52dd528872f12c50375801a58aaf5ae91113f" +checksum = "daa30058ec7d3511fbc229e4f9e696a35abd07ec5b82e635eff864a2726217e4" dependencies = [ "bstr", "itoa", "jiff", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1712,7 +1725,7 @@ dependencies = [ "bstr", "gix-hash", "gix-object", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1732,7 +1745,7 @@ dependencies = [ "gix-trace", "gix-utils", "gix-worktree", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1748,7 +1761,7 @@ dependencies = [ "gix-path", "gix-ref", "gix-sec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1769,7 +1782,7 @@ dependencies = [ "parking_lot", "prodash", "sha1_smol", - "thiserror 2.0.10", + "thiserror 2.0.12", "walkdir", ] @@ -1791,7 +1804,7 @@ dependencies = [ "gix-trace", "gix-utils", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1824,7 +1837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b5eccc17194ed0e67d49285e4853307e4147e95407f91c1c3e4a13ba9f4e4ce" dependencies = [ "faster-hex", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1874,9 +1887,9 @@ dependencies = [ "itoa", "libc", "memmap2", - "rustix", + "rustix 0.38.44", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1887,7 +1900,7 @@ checksum = "1cd3ab68a452db63d9f3ebdacb10f30dba1fa0d31ac64f4203d395ed1102d940" dependencies = [ "gix-tempfile", "gix-utils", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1903,7 +1916,7 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1923,8 +1936,8 @@ dependencies = [ "gix-validate", "itoa", "smallvec", - "thiserror 2.0.10", - "winnow", + "thiserror 2.0.12", + "winnow 0.6.26", ] [[package]] @@ -1945,7 +1958,7 @@ dependencies = [ "gix-quote", "parking_lot", "tempfile", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -1965,44 +1978,44 @@ dependencies = [ "memmap2", "parking_lot", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "gix-packetline" -version = "0.18.2" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "911aeea8b2dabeed2f775af9906152a1f0109787074daf9e64224e3892dde453" +checksum = "123844a70cf4d5352441dc06bab0da8aef61be94ec239cb631e0ba01dc6d3a04" dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "gix-packetline-blocking" -version = "0.18.1" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce9004ce1bc00fd538b11c1ec8141a1558fb3af3d2b7ac1ac5c41881f9e42d2a" +checksum = "1ecf3ea2e105c7e45587bac04099824301262a6c43357fad5205da36dbb233b3" dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "gix-path" -version = "0.10.14" +version = "0.10.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c40f12bb65a8299be0cfb90fe718e3be236b7a94b434877012980863a883a99f" +checksum = "f910668e2f6b2a55ff35a1f04df88a1a049f7b868507f4cbeeaa220eaba7be87" dependencies = [ "bstr", "gix-trace", "home", "once_cell", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2017,7 +2030,7 @@ dependencies = [ "gix-config-value", "gix-glob", "gix-path", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2029,8 +2042,8 @@ dependencies = [ "gix-command", "gix-config-value", "parking_lot", - "rustix", - "thiserror 2.0.10", + "rustix 0.38.44", + "thiserror 2.0.12", ] [[package]] @@ -2055,19 +2068,19 @@ dependencies = [ "gix-transport", "gix-utils", "maybe-async", - "thiserror 2.0.10", - "winnow", + "thiserror 2.0.12", + "winnow 0.6.26", ] [[package]] name = "gix-quote" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a1e282216ec2ab2816cd57e6ed88f8009e634aec47562883c05ac8a7009a63" +checksum = "e49357fccdb0c85c0d3a3292a9f6db32d9b3535959b5471bb9624908f4a066c6" dependencies = [ "bstr", "gix-utils", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2087,8 +2100,8 @@ dependencies = [ "gix-utils", "gix-validate", "memmap2", - "thiserror 2.0.10", - "winnow", + "thiserror 2.0.12", + "winnow 0.6.26", ] [[package]] @@ -2102,7 +2115,7 @@ dependencies = [ "gix-revision", "gix-validate", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2117,7 +2130,7 @@ dependencies = [ "gix-hash", "gix-object", "gix-revwalk", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2132,14 +2145,14 @@ dependencies = [ "gix-hashtable", "gix-object", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] name = "gix-sec" -version = "0.10.10" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8b876ef997a955397809a2ec398d6a45b7a55b4918f2446344330f778d14fd6" +checksum = "47aeb0f13de9ef2f3033f5ff218de30f44db827ac9f1286f9ef050aacddd5888" dependencies = [ "bitflags 2.9.0", "gix-path", @@ -2156,7 +2169,7 @@ dependencies = [ "bstr", "gix-hash", "gix-lock", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2171,7 +2184,7 @@ dependencies = [ "gix-pathspec", "gix-refspec", "gix-url", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2209,7 +2222,7 @@ dependencies = [ "gix-quote", "gix-sec", "gix-url", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2226,7 +2239,7 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2239,15 +2252,15 @@ dependencies = [ "gix-features", "gix-path", "percent-encoding", - "thiserror 2.0.10", + "thiserror 2.0.12", "url", ] [[package]] name = "gix-utils" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba427e3e9599508ed98a6ddf8ed05493db114564e338e41f6a996d2e4790335f" +checksum = "ff08f24e03ac8916c478c8419d7d3c33393da9bb41fa4c24455d5406aeefd35f" dependencies = [ "bstr", "fastrand", @@ -2256,12 +2269,12 @@ dependencies = [ [[package]] name = "gix-validate" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd520d09f9f585b34b32aba1d0b36ada89ab7fefb54a8ca3fe37fc482a750937" +checksum = "34b5f1253109da6c79ed7cf6e1e38437080bb6d704c76af14c93e2f255234084" dependencies = [ "bstr", - "thiserror 2.0.10", + "thiserror 2.0.12", ] [[package]] @@ -2291,9 +2304,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "globset" -version = "0.4.15" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" dependencies = [ "aho-corasick", "bstr", @@ -2309,7 +2322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2398,9 +2411,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -2428,12 +2441,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -2441,21 +2454,21 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "hyper" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", @@ -2490,9 +2503,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-channel", @@ -2500,6 +2513,7 @@ dependencies = [ "http", "http-body", "hyper", + "libc", "pin-project-lite", "socket2", "tokio", @@ -2548,9 +2562,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -2572,9 +2586,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -2593,9 +2607,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -2675,7 +2689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" dependencies = [ "bitmaps", - "rand_core", + "rand_core 0.6.4", "rand_xoshiro", "sized-chunks", "typenum", @@ -2684,9 +2698,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -2694,9 +2708,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.9" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ "console", "number_prefix", @@ -2717,9 +2731,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.10.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "is_ci" @@ -2753,16 +2767,17 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.1.21" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0ce60560149333a8e41ca7dc78799c47c5fd435e2bc18faf6a054382eec037" +checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" dependencies = [ + "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", @@ -2771,35 +2786,47 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "jiff-static" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "jiff-tzdb" -version = "0.1.1" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91335e575850c5c4c673b9bd467b0e025f164ca59d0564f69d0c2ee0ffad4653" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" [[package]] name = "jiff-tzdb-platform" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9835f0060a626fe59f160437bc725491a6af23133ea906500027d1bd2f8f4329" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" dependencies = [ "jiff-tzdb", ] [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.2", "libc", ] [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -2828,9 +2855,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libdbus-sys" @@ -2868,9 +2895,9 @@ dependencies = [ [[package]] name = "libnghttp2-sys" -version = "0.1.10+1.61.0" +version = "0.1.11+1.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "959c25552127d2e1fa72f0e52548ec04fc386e827ba71a7bd01db46a447dc135" +checksum = "1b6c24e48a7167cffa7119da39d577fa482e66c688a4aac016bee862e1a713c4" dependencies = [ "cc", "libc", @@ -2900,9 +2927,9 @@ dependencies = [ [[package]] name = "libssh2-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +checksum = "220e4f05ad4a218192533b300327f5150e809b54c4ec83b5a1d91833601811b9" dependencies = [ "cc", "libc", @@ -2914,9 +2941,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.21" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" dependencies = [ "cc", "libc", @@ -2930,11 +2957,17 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" + [[package]] name = "litemap" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "lock_api" @@ -2948,9 +2981,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" dependencies = [ "serde", ] @@ -3011,9 +3044,9 @@ dependencies = [ [[package]] name = "miette" -version = "7.4.0" +version = "7.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317f146e2eb7021892722af37cf1b971f0a70c8406f487e24952667616192c64" +checksum = "1a955165f87b37fd1862df2a59547ac542c77ef6d17c666f619d1ad22dd89484" dependencies = [ "backtrace", "backtrace-ext", @@ -3031,9 +3064,9 @@ dependencies = [ [[package]] name = "miette-derive" -version = "7.4.0" +version = "7.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c9b935fbe1d6cbd1dac857b54a688145e2d93f48db36010514d0f612d0ad67" +checksum = "bf45bf44ab49be92fd1227a3be6fc6f617f1a337c06af54981048574d8783147" dependencies = [ "proc-macro2", "quote", @@ -3054,9 +3087,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.2" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430" dependencies = [ "adler2", ] @@ -3069,7 +3102,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -3186,9 +3219,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "opener" @@ -3230,24 +3263,24 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.4.1+3.4.0" +version = "300.4.2+3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" +checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" dependencies = [ "cc", "libc", @@ -3273,9 +3306,9 @@ dependencies = [ [[package]] name = "orion" -version = "0.17.7" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ab5415cf60cd271259e576f2ddee7a5f9fed42659035224c01af766943fad3" +checksum = "bf2e0b749a7c5fb3d43f06f19eff59b253b5480fa146533676cea27c3606530b" dependencies = [ "fiat-crypto", "subtle", @@ -3284,9 +3317,9 @@ dependencies = [ [[package]] name = "os_info" -version = "3.9.2" +version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6520c8cc998c5741ee68ec1dc369fc47e5f0ea5320018ecf2a1ccd6328f48b" +checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" dependencies = [ "log", "windows-sys 0.52.0", @@ -3300,15 +3333,15 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" +checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564" [[package]] name = "p384" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" dependencies = [ "ecdsa", "elliptic-curve", @@ -3350,16 +3383,16 @@ dependencies = [ [[package]] name = "pasetors" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2e0504622b293d583952413ab7c578c70a0101b8c0b7eff51ce23b111e986f2" +checksum = "c54944fa25a6e7c9c5b3315f118d360cc00d555cf53bb2b2fdf32dd31c71b729" dependencies = [ "ct-codecs", "ed25519-compact", - "getrandom", + "getrandom 0.3.2", "orion", "p384", - "rand_core", + "rand_core 0.6.4", "regex", "serde", "serde_json", @@ -3414,15 +3447,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] name = "portable-atomic-util" @@ -3441,11 +3474,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy", + "zerocopy 0.8.24", ] [[package]] @@ -3459,27 +3492,27 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "prodash" -version = "29.0.0" +version = "29.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a266d8d6020c61a437be704c5e618037588e1985c7dbb7bf8d265db84cffe325" +checksum = "9ee7ce24c980b976607e2d6ae4aae92827994d23fed71659c3ede3f92528b58b" dependencies = [ "log", "parking_lot", @@ -3487,37 +3520,39 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", "rustls", "socket2", - "thiserror 2.0.10", + "thiserror 2.0.12", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", - "getrandom", - "rand", + "getrandom 0.3.2", + "rand 0.9.0", "ring", "rustc-hash", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.10", + "thiserror 2.0.12", "tinyvec", "tracing", "web-time", @@ -3525,9 +3560,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" +checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" dependencies = [ "cfg_aliases", "libc", @@ -3539,13 +3574,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "radium" version = "0.7.0" @@ -3559,8 +3600,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy 0.8.24", ] [[package]] @@ -3570,7 +3622,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -3579,7 +3641,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", ] [[package]] @@ -3588,14 +3659,14 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ "bitflags 2.9.0", ] @@ -3606,7 +3677,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror 1.0.69", ] @@ -3657,9 +3728,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.12" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64", "bytes", @@ -3711,15 +3782,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -3746,15 +3816,15 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-stable-hash" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2febf9acc5ee5e99d1ad0afcdbccc02d87aa3f857a1f01f825b80eacf8edfcd1" +checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" [[package]] name = "rustfix" @@ -3770,22 +3840,35 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.9.3", "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "log", "once_cell", @@ -3807,18 +3890,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" dependencies = [ "web-time", ] [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ "ring", "rustls-pki-types", @@ -3827,9 +3910,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ruzstd" @@ -3842,9 +3925,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -3909,9 +3992,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] @@ -3927,9 +4010,9 @@ dependencies = [ [[package]] name = "serde-untagged" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2676ba99bd82f75cae5cbd2c8eda6fa0b8760f18978ea840e980dd5567b5c5b6" +checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e" dependencies = [ "erased-serde", "serde", @@ -3959,18 +4042,18 @@ dependencies = [ [[package]] name = "serde_ignored" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8e319a36d1b52126a0d608f24e93b2d81297091818cd70625fcf50a15d84ddf" +checksum = "566da67d80e92e009728b3731ff0e5360cb181432b8ca73ea30bb1d170700d76" dependencies = [ "serde", ] [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -3978,15 +4061,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_plain" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" -dependencies = [ - "serde", -] - [[package]] name = "serde_spanned" version = "0.6.8" @@ -4010,9 +4084,9 @@ dependencies = [ [[package]] name = "serialport" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ecfc4858c2266c7695d8b8460bbd612fa81bd2e250f5f0dd16195e4b4f8b3d8" +checksum = "2daa7abb9b965493e3c8f4184c6f46435484ff2538a332b886788cf6768b927b" dependencies = [ "bitflags 2.9.0", "cfg-if", @@ -4118,7 +4192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -4148,26 +4222,20 @@ checksum = "e794b692443f8d9b677cd41c867347df2902844d7b7f5775f47fcb37b9e7965b" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "spki" version = "0.7.3" @@ -4247,9 +4315,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.96" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -4284,9 +4352,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.43" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ "filetime", "libc", @@ -4294,36 +4362,35 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.15.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand", - "getrandom", + "getrandom 0.3.2", "once_cell", - "rustix", + "rustix 1.0.5", "windows-sys 0.59.0", ] [[package]] name = "terminal_size" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" +checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix", + "rustix 1.0.5", "windows-sys 0.59.0", ] [[package]] name = "textwrap" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" dependencies = [ "unicode-linebreak", - "unicode-width 0.1.14", + "unicode-width 0.2.0", ] [[package]] @@ -4337,11 +4404,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.10", + "thiserror-impl 2.0.12", ] [[package]] @@ -4357,9 +4424,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.10" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -4378,9 +4445,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -4393,15 +4460,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -4419,9 +4486,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -4434,9 +4501,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", "bytes", @@ -4449,9 +4516,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", "tokio", @@ -4459,9 +4526,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", @@ -4480,15 +4547,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.7.4", ] [[package]] @@ -4614,15 +4681,15 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "typeid" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unescaper" @@ -4647,9 +4714,9 @@ checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-linebreak" @@ -4666,6 +4733,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + [[package]] name = "unicode-width" version = "0.1.14" @@ -4753,9 +4826,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vcpkg" @@ -4794,22 +4867,32 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", @@ -4821,9 +4904,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", @@ -4834,9 +4917,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4844,9 +4927,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -4857,15 +4940,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -4883,9 +4969,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.7" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" dependencies = [ "rustls-pki-types", ] @@ -4921,34 +5007,39 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + [[package]] name = "windows-registry" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ "windows-result", "windows-strings", - "windows-targets 0.52.6", + "windows-targets 0.53.0", ] [[package]] name = "windows-result" -version = "0.2.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-result", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -5002,13 +5093,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -5021,6 +5128,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -5033,6 +5146,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -5045,12 +5164,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -5063,6 +5194,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -5075,6 +5212,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -5087,6 +5230,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -5099,15 +5248,39 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.6.22" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" +checksum = "1e90edd2ac1aa278a5c4599b1d89cf03074b610800f866d4026dc199d7929a28" dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -5159,8 +5332,16 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", ] [[package]] @@ -5174,20 +5355,31 @@ dependencies = [ "syn", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index c97be745..ae8dc3ea 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -20,21 +20,17 @@ use serialport::{SerialPort, UsbPortInfo}; #[cfg(unix)] use self::reset::UnixTightReset; -pub use self::{ - command::{Command, CommandType}, - decoder::{SlipDecoder, SlipError}, - encoder::SlipEncoder, - reset::{ - construct_reset_strategy_sequence, hard_reset, reset_after_flash, soft_reset, ClassicReset, - ResetAfterOperation, ResetBeforeOperation, ResetStrategy, UsbJtagSerialReset, - }, +pub use self::reset::{ + construct_reset_strategy_sequence, hard_reset, reset_after_flash, soft_reset, ClassicReset, + ResetAfterOperation, ResetBeforeOperation, ResetStrategy, UsbJtagSerialReset, }; use crate::{ error::{ConnectionError, Error, ResultExt, RomError, RomErrorKind}, targets::Chip, }; -use super::command; +use super::command::{Command, CommandType}; +use super::slip::{decoder::SlipDecoder, encoder::SlipEncoder}; pub(crate) mod reset; const MAX_CONNECT_ATTEMPTS: usize = 7; @@ -604,332 +600,3 @@ impl Connection { self.port_info.pid == USB_SERIAL_JTAG_PID } } - -mod encoder { - use core::fmt::Debug; - use embedded_io::Write; - - const END: u8 = 0xC0; - const ESC: u8 = 0xDB; - const ESC_END: u8 = 0xDC; - const ESC_ESC: u8 = 0xDD; - - #[derive(Debug)] - pub struct SlipEncoder<'a, W: Write> { - writer: &'a mut W, - len: usize, - } - - impl<'a, W: Write> SlipEncoder<'a, W> { - /// Creates a new encoder context - pub fn new(writer: &'a mut W) -> Result { - let len = writer.write(&[END])?; - Ok(Self { writer, len }) - } - - pub fn finish(mut self) -> Result { - self.len += self.writer.write(&[END])?; - Ok(self.len) - } - } - - impl embedded_io::ErrorType for SlipEncoder<'_, W> { - type Error = W::Error; - } - - impl Write for SlipEncoder<'_, W> { - /// Writes the given buffer replacing the END and ESC bytes - /// - /// See https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/serial-protocol.html#low-level-protocol - fn write(&mut self, buf: &[u8]) -> Result { - for value in buf.iter() { - match *value { - END => { - self.len += self.writer.write(&[ESC, ESC_END])?; - } - ESC => { - self.len += self.writer.write(&[ESC, ESC_ESC])?; - } - _ => { - self.len += self.writer.write(&[*value])?; - } - } - } - - Ok(buf.len()) - } - - fn flush(&mut self) -> Result<(), W::Error> { - self.writer.flush() - } - } -} - -mod decoder { - /// SLIP end of packet token - const END: u8 = 0xC0; - - /// SLIP escape token - const ESC: u8 = 0xDB; - - /// SLIP escaped 0xC0 token - const ESC_END: u8 = 0xDC; - - /// SLIP escaped 0xDB token - const ESC_ESC: u8 = 0xDD; - - /// Recommended maximum SLIP packet size per RFC 1055 - #[allow(dead_code)] - const MAX_PACKET_SIZE: usize = 1006; - use core::convert::Infallible; - use embedded_io::{Read, Write}; - - /// SLIP decoder error type - #[derive(Debug)] - pub enum SlipError { - FramingError, - OversizedPacket, - EndOfStream, - ReadError(RE), - WriteError(WE), - } - - pub type SlipResult = std::result::Result>; - - #[derive(Debug)] - enum State { - Normal, - Error, - Escape, - } - - /// SLIP decoder context - #[derive(Debug)] - pub struct SlipDecoder { - count: usize, - state: State, - } - - // Unfortunately even the never type doesn't auto-coerce - fn coerce_infallible(err: SlipError) -> SlipError { - match err { - SlipError::ReadError(_) => { - unreachable!() - } - SlipError::WriteError(e) => SlipError::WriteError(e), - SlipError::FramingError => SlipError::FramingError, - SlipError::OversizedPacket => SlipError::OversizedPacket, - SlipError::EndOfStream => SlipError::EndOfStream, - } - } - - impl SlipDecoder { - /// Creates a new context with the given maximum buffer size. - pub fn new() -> Self { - Self { - count: 0usize, - state: State::Normal, - } - } - - fn push( - &mut self, - sink: &mut W, - value: u8, - ) -> self::SlipResult { - match sink.write(&[value]) { - Ok(len) => { - if len != 1 { - Err(SlipError::OversizedPacket) - } else { - self.count += 1; - Ok(1usize) - } - } - Err(error) => Err(SlipError::WriteError(error)), - } - } - - /// Attempts to decode a single SLIP frame from the given source. - /// - /// # Arguments - /// - /// * `source` - Encoded SLIP data source implementing the std::io::Read - /// trait - /// - /// Returns a Vec containing a decoded message or an empty Vec if - /// of the source data was reached. - /// - pub fn decode( - &mut self, - source: &mut R, - sink: &mut W, - ) -> self::SlipResult { - loop { - let mut buf = [0u8; 16]; - let read_amount = source.read(&mut buf).map_err(SlipError::ReadError)?; - - for value in buf[0..read_amount].iter().cloned() { - match self.state { - State::Normal => match value { - END => { - if self.count > 0 { - let len = self.count; - - self.count = 0usize; - - return Ok(len); - } - } - ESC => { - self.state = State::Escape; - } - _ => { - self.push(sink, value).map_err(coerce_infallible)?; - } - }, - State::Error => { - if value == END { - self.count = 0usize; - self.state = State::Normal; - } - } - State::Escape => match value { - ESC_END => { - self.push(sink, END).map_err(coerce_infallible)?; - self.state = State::Normal; - } - ESC_ESC => { - self.push(sink, ESC).map_err(coerce_infallible)?; - self.state = State::Normal; - } - _ => { - self.state = State::Error; - - return Err(SlipError::FramingError); - } - }, - } - } - - if read_amount < buf.len() { - Err(SlipError::EndOfStream)? - } - } - } - } - - impl Default for SlipDecoder { - fn default() -> Self { - Self::new() - } - } - - #[cfg(test)] - mod tests { - use super::*; - - #[test] - fn empty_decode() { - const INPUT: [u8; 2] = [0xc0, 0xc0]; - - let mut slip = SlipDecoder::new(); - let mut buf: Vec = Vec::new(); - let res = slip.decode(&mut INPUT.as_ref(), &mut buf); - assert!(res.is_err()); - assert!(buf.is_empty()); - } - - #[test] - fn simple_decode() { - const INPUT: [u8; 7] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0]; - const DATA: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05]; - - let mut slip = SlipDecoder::new(); - let mut buf = [0u8; DATA.len()]; - let len = slip.decode(&mut INPUT.as_ref(), &mut buf.as_mut()).unwrap(); - assert_eq!(DATA.len(), len); - assert_eq!(DATA.len(), buf.len()); - assert_eq!(&DATA, &buf); - } - - /// Ensure that [ESC, ESC_END] -> [END] - #[test] - fn decode_esc_then_esc_end_sequence() { - const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdc, 0x03, 0xc0]; - const DATA: [u8; 3] = [0x01, 0xc0, 0x03]; - - let mut slip = SlipDecoder::new(); - let mut buf: Vec = Vec::new(); - let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap(); - assert_eq!(DATA.len(), len); - assert_eq!(DATA.len(), buf.len()); - assert_eq!(&DATA, buf.as_slice()); - } - - /// Ensure that [ESC, ESC_ESC] -> [ESC] - #[test] - fn decode_esc_then_esc_esc_sequence() { - const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdd, 0x03, 0xc0]; - const DATA: [u8; 3] = [0x01, 0xdb, 0x03]; - - let mut slip = SlipDecoder::new(); - let mut buf: Vec = Vec::new(); - let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap(); - assert_eq!(DATA.len(), len); - assert_eq!(DATA.len(), buf.len()); - assert_eq!(&DATA, buf.as_slice()); - } - - #[test] - fn multi_part_decode() { - const INPUT_1: [u8; 6] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05]; - const INPUT_2: [u8; 6] = [0x05, 0x06, 0x07, 0x08, 0x09, 0xc0]; - const DATA: [u8; 10] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09]; - - let mut slip = SlipDecoder::new(); - let mut buf: Vec = Vec::new(); - - { - let res = slip.decode(&mut INPUT_1.as_ref(), &mut buf); - assert!(res.is_err()); - assert_eq!(5, buf.len()); - } - - { - let len = slip.decode(&mut INPUT_2.as_ref(), &mut buf).unwrap(); - assert_eq!(DATA.len(), len); - assert_eq!(DATA.len(), buf.len()); - assert_eq!(&DATA, buf.as_slice()); - } - } - - #[test] - fn compound_decode() { - const INPUT: [u8; 13] = [ - 0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0, 0x05, 0x06, 0x07, 0x08, 0x09, 0xc0, - ]; - const DATA_1: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05]; - const DATA_2: [u8; 5] = [0x05, 0x06, 0x07, 0x08, 0x09]; - - let mut slip = SlipDecoder::new(); - let reader = &mut INPUT.as_ref(); - - { - let mut buf: Vec = Vec::new(); - let len = slip.decode(reader, &mut buf).unwrap(); - assert_eq!(DATA_1.len(), len); - assert_eq!(DATA_1.len(), buf.len()); - assert_eq!(&DATA_1, buf.as_slice()); - } - - { - let mut buf: Vec = Vec::new(); - let len = slip.decode(reader, &mut buf).unwrap(); - assert_eq!(DATA_2.len(), len); - assert_eq!(DATA_2.len(), buf.len()); - assert_eq!(&DATA_2, buf.as_slice()); - } - } - } -} diff --git a/espflash/src/connection/reset.rs b/espflash/src/connection/reset.rs index 85279743..5ab0b241 100644 --- a/espflash/src/connection/reset.rs +++ b/espflash/src/connection/reset.rs @@ -11,12 +11,8 @@ use log::debug; use serialport::SerialPort; use strum::{Display, EnumIter, EnumString, VariantNames}; -use super::{ - command::{Command, CommandType}, - Connection, - Port, - USB_SERIAL_JTAG_PID, -}; +use super::{Connection, Port, USB_SERIAL_JTAG_PID}; +use crate::command::{Command, CommandType}; use crate::{flasher::FLASH_WRITE_SIZE, Error}; /// Default time to wait before releasing the boot pin after a reset diff --git a/espflash/src/error.rs b/espflash/src/error.rs index 7bf7f378..059042dd 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -12,8 +12,7 @@ use std::io; #[cfg(feature = "std")] use miette::Diagnostic; -#[cfg(feature = "serialport")] -use crate::connection::SlipError; +use crate::slip::decoder::SlipError; use strum::VariantNames; use thiserror::Error; diff --git a/espflash/src/lib.rs b/espflash/src/lib.rs index 62a2e75c..a315e17c 100644 --- a/espflash/src/lib.rs +++ b/espflash/src/lib.rs @@ -38,6 +38,7 @@ pub mod connection; pub mod command; pub mod flasher; pub mod image_format; +pub mod slip; pub mod targets; mod error; diff --git a/espflash/src/slip.rs b/espflash/src/slip.rs new file mode 100644 index 00000000..89d24ce6 --- /dev/null +++ b/espflash/src/slip.rs @@ -0,0 +1,328 @@ +pub mod encoder { + use core::fmt::Debug; + use embedded_io::Write; + + const END: u8 = 0xC0; + const ESC: u8 = 0xDB; + const ESC_END: u8 = 0xDC; + const ESC_ESC: u8 = 0xDD; + + #[derive(Debug)] + pub struct SlipEncoder<'a, W: Write> { + writer: &'a mut W, + len: usize, + } + + impl<'a, W: Write> SlipEncoder<'a, W> { + /// Creates a new encoder context + pub fn new(writer: &'a mut W) -> Result { + let len = writer.write(&[END])?; + Ok(Self { writer, len }) + } + + pub fn finish(mut self) -> Result { + self.len += self.writer.write(&[END])?; + Ok(self.len) + } + } + + impl embedded_io::ErrorType for SlipEncoder<'_, W> { + type Error = W::Error; + } + + impl Write for SlipEncoder<'_, W> { + /// Writes the given buffer replacing the END and ESC bytes + /// + /// See https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/serial-protocol.html#low-level-protocol + fn write(&mut self, buf: &[u8]) -> Result { + for value in buf.iter() { + match *value { + END => { + self.len += self.writer.write(&[ESC, ESC_END])?; + } + ESC => { + self.len += self.writer.write(&[ESC, ESC_ESC])?; + } + _ => { + self.len += self.writer.write(&[*value])?; + } + } + } + + Ok(buf.len()) + } + + fn flush(&mut self) -> Result<(), W::Error> { + self.writer.flush() + } + } +} + +pub mod decoder { + /// SLIP end of packet token + const END: u8 = 0xC0; + + /// SLIP escape token + const ESC: u8 = 0xDB; + + /// SLIP escaped 0xC0 token + const ESC_END: u8 = 0xDC; + + /// SLIP escaped 0xDB token + const ESC_ESC: u8 = 0xDD; + + /// Recommended maximum SLIP packet size per RFC 1055 + #[allow(dead_code)] + const MAX_PACKET_SIZE: usize = 1006; + use core::convert::Infallible; + use embedded_io::{Read, Write}; + + /// SLIP decoder error type + #[derive(Debug)] + pub enum SlipError { + FramingError, + OversizedPacket, + EndOfStream, + ReadError(RE), + WriteError(WE), + } + + pub type SlipResult = core::result::Result>; + + #[derive(Debug)] + enum State { + Normal, + Error, + Escape, + } + + /// SLIP decoder context + #[derive(Debug)] + pub struct SlipDecoder { + count: usize, + state: State, + } + + // Unfortunately even the never type doesn't auto-coerce + fn coerce_infallible(err: SlipError) -> SlipError { + match err { + SlipError::ReadError(_) => { + unreachable!() + } + SlipError::WriteError(e) => SlipError::WriteError(e), + SlipError::FramingError => SlipError::FramingError, + SlipError::OversizedPacket => SlipError::OversizedPacket, + SlipError::EndOfStream => SlipError::EndOfStream, + } + } + + impl SlipDecoder { + /// Creates a new context with the given maximum buffer size. + pub fn new() -> Self { + Self { + count: 0usize, + state: State::Normal, + } + } + + fn push( + &mut self, + sink: &mut W, + value: u8, + ) -> self::SlipResult { + match sink.write(&[value]) { + Ok(len) => { + if len != 1 { + Err(SlipError::OversizedPacket) + } else { + self.count += 1; + Ok(1usize) + } + } + Err(error) => Err(SlipError::WriteError(error)), + } + } + + /// Attempts to decode a single SLIP frame from the given source. + /// + /// # Arguments + /// + /// * `source` - Encoded SLIP data source implementing the std::io::Read + /// trait + /// + /// Returns a Vec containing a decoded message or an empty Vec if + /// of the source data was reached. + /// + pub fn decode( + &mut self, + source: &mut R, + sink: &mut W, + ) -> self::SlipResult { + loop { + let mut buf = [0u8; 16]; + let read_amount = source.read(&mut buf).map_err(SlipError::ReadError)?; + + for value in buf[0..read_amount].iter().cloned() { + match self.state { + State::Normal => match value { + END => { + if self.count > 0 { + let len = self.count; + + self.count = 0usize; + + return Ok(len); + } + } + ESC => { + self.state = State::Escape; + } + _ => { + self.push(sink, value).map_err(coerce_infallible)?; + } + }, + State::Error => { + if value == END { + self.count = 0usize; + self.state = State::Normal; + } + } + State::Escape => match value { + ESC_END => { + self.push(sink, END).map_err(coerce_infallible)?; + self.state = State::Normal; + } + ESC_ESC => { + self.push(sink, ESC).map_err(coerce_infallible)?; + self.state = State::Normal; + } + _ => { + self.state = State::Error; + + return Err(SlipError::FramingError); + } + }, + } + } + + if read_amount < buf.len() { + Err(SlipError::EndOfStream)? + } + } + } + } + + impl Default for SlipDecoder { + fn default() -> Self { + Self::new() + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + fn empty_decode() { + const INPUT: [u8; 2] = [0xc0, 0xc0]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + let res = slip.decode(&mut INPUT.as_ref(), &mut buf); + assert!(res.is_err()); + assert!(buf.is_empty()); + } + + #[test] + fn simple_decode() { + const INPUT: [u8; 7] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0]; + const DATA: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05]; + + let mut slip = SlipDecoder::new(); + let mut buf = [0u8; DATA.len()]; + let len = slip.decode(&mut INPUT.as_ref(), &mut buf.as_mut()).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, &buf); + } + + /// Ensure that [ESC, ESC_END] -> [END] + #[test] + fn decode_esc_then_esc_end_sequence() { + const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdc, 0x03, 0xc0]; + const DATA: [u8; 3] = [0x01, 0xc0, 0x03]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, buf.as_slice()); + } + + /// Ensure that [ESC, ESC_ESC] -> [ESC] + #[test] + fn decode_esc_then_esc_esc_sequence() { + const INPUT: [u8; 6] = [0xc0, 0x01, 0xdb, 0xdd, 0x03, 0xc0]; + const DATA: [u8; 3] = [0x01, 0xdb, 0x03]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + let len = slip.decode(&mut INPUT.as_ref(), &mut buf).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, buf.as_slice()); + } + + #[test] + fn multi_part_decode() { + const INPUT_1: [u8; 6] = [0xc0, 0x01, 0x02, 0x03, 0x04, 0x05]; + const INPUT_2: [u8; 6] = [0x05, 0x06, 0x07, 0x08, 0x09, 0xc0]; + const DATA: [u8; 10] = [0x01, 0x02, 0x03, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09]; + + let mut slip = SlipDecoder::new(); + let mut buf: Vec = Vec::new(); + + { + let res = slip.decode(&mut INPUT_1.as_ref(), &mut buf); + assert!(res.is_err()); + assert_eq!(5, buf.len()); + } + + { + let len = slip.decode(&mut INPUT_2.as_ref(), &mut buf).unwrap(); + assert_eq!(DATA.len(), len); + assert_eq!(DATA.len(), buf.len()); + assert_eq!(&DATA, buf.as_slice()); + } + } + + #[test] + fn compound_decode() { + const INPUT: [u8; 13] = [ + 0xc0, 0x01, 0x02, 0x03, 0x04, 0x05, 0xc0, 0x05, 0x06, 0x07, 0x08, 0x09, 0xc0, + ]; + const DATA_1: [u8; 5] = [0x01, 0x02, 0x03, 0x04, 0x05]; + const DATA_2: [u8; 5] = [0x05, 0x06, 0x07, 0x08, 0x09]; + + let mut slip = SlipDecoder::new(); + let reader = &mut INPUT.as_ref(); + + { + let mut buf: Vec = Vec::new(); + let len = slip.decode(reader, &mut buf).unwrap(); + assert_eq!(DATA_1.len(), len); + assert_eq!(DATA_1.len(), buf.len()); + assert_eq!(&DATA_1, buf.as_slice()); + } + + { + let mut buf: Vec = Vec::new(); + let len = slip.decode(reader, &mut buf).unwrap(); + assert_eq!(DATA_2.len(), len); + assert_eq!(DATA_2.len(), buf.len()); + assert_eq!(&DATA_2, buf.as_slice()); + } + } + } +} From 4a995942d595526617d36054b7b6e027cc5e8f36 Mon Sep 17 00:00:00 2001 From: ferris Date: Mon, 7 Apr 2025 16:56:20 +0200 Subject: [PATCH 6/6] Move CommandResponse to command.rs --- espflash/src/command.rs | 72 +++++++++++++++++++++++++++++++++- espflash/src/connection/mod.rs | 68 +------------------------------- 2 files changed, 72 insertions(+), 68 deletions(-) diff --git a/espflash/src/command.rs b/espflash/src/command.rs index e82697bd..4fa57dda 100644 --- a/espflash/src/command.rs +++ b/espflash/src/command.rs @@ -2,12 +2,16 @@ use core::{mem::size_of, time::Duration}; +use alloc::vec::Vec; use embedded_io::Write; use bytemuck::{bytes_of, Pod, Zeroable}; use strum::Display; -use crate::flasher::{SpiAttachParams, SpiSetParams}; +use crate::{ + flasher::{SpiAttachParams, SpiSetParams}, + Error, +}; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(3); const ERASE_REGION_TIMEOUT_PER_MB: Duration = Duration::from_secs(30); @@ -555,3 +559,69 @@ fn checksum(data: &[u8], mut checksum: u8) -> u8 { checksum } + +#[derive(Debug, Clone)] +pub enum CommandResponseValue { + ValueU32(u32), + ValueU128(u128), + Vector(Vec), +} + +impl TryInto for CommandResponseValue { + type Error = Error; + + fn try_into(self) -> Result { + match self { + CommandResponseValue::ValueU32(value) => Ok(value), + CommandResponseValue::ValueU128(_) => Err(Error::InvalidResponse( + "expected `u32` but found `u128`".into(), + )), + CommandResponseValue::Vector(_) => Err(Error::InvalidResponse( + "expected `u32` but found `Vec`".into(), + )), + } + } +} + +impl TryInto for CommandResponseValue { + type Error = Error; + + fn try_into(self) -> Result { + match self { + CommandResponseValue::ValueU32(_) => Err(Error::InvalidResponse( + "expected `u128` but found `u32`".into(), + )), + CommandResponseValue::ValueU128(value) => Ok(value), + CommandResponseValue::Vector(_) => Err(Error::InvalidResponse( + "expected `u128` but found `Vec`".into(), + )), + } + } +} + +impl TryInto> for CommandResponseValue { + type Error = Error; + + fn try_into(self) -> Result, Self::Error> { + match self { + CommandResponseValue::ValueU32(_) => Err(Error::InvalidResponse( + "expected `Vec` but found `u32`".into(), + )), + CommandResponseValue::ValueU128(_) => Err(Error::InvalidResponse( + "expected `Vec` but found `u128`".into(), + )), + CommandResponseValue::Vector(value) => Ok(value), + } + } +} + +/// A response from a target device following a command +#[derive(Debug, Clone)] +pub struct CommandResponse { + pub resp: u8, + pub return_op: u8, + pub return_length: u16, + pub value: CommandResponseValue, + pub error: u8, + pub status: u8, +} diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index ae8dc3ea..86e62f94 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -29,7 +29,7 @@ use crate::{ targets::Chip, }; -use super::command::{Command, CommandType}; +use super::command::{Command, CommandResponse, CommandResponseValue, CommandType}; use super::slip::{decoder::SlipDecoder, encoder::SlipEncoder}; pub(crate) mod reset; @@ -42,72 +42,6 @@ pub type Port = serialport::TTYPort; #[cfg(windows)] pub type Port = serialport::COMPort; -#[derive(Debug, Clone)] -pub enum CommandResponseValue { - ValueU32(u32), - ValueU128(u128), - Vector(Vec), -} - -impl TryInto for CommandResponseValue { - type Error = Error; - - fn try_into(self) -> Result { - match self { - CommandResponseValue::ValueU32(value) => Ok(value), - CommandResponseValue::ValueU128(_) => Err(Error::InvalidResponse( - "expected `u32` but found `u128`".into(), - )), - CommandResponseValue::Vector(_) => Err(Error::InvalidResponse( - "expected `u32` but found `Vec`".into(), - )), - } - } -} - -impl TryInto for CommandResponseValue { - type Error = Error; - - fn try_into(self) -> Result { - match self { - CommandResponseValue::ValueU32(_) => Err(Error::InvalidResponse( - "expected `u128` but found `u32`".into(), - )), - CommandResponseValue::ValueU128(value) => Ok(value), - CommandResponseValue::Vector(_) => Err(Error::InvalidResponse( - "expected `u128` but found `Vec`".into(), - )), - } - } -} - -impl TryInto> for CommandResponseValue { - type Error = Error; - - fn try_into(self) -> Result, Self::Error> { - match self { - CommandResponseValue::ValueU32(_) => Err(Error::InvalidResponse( - "expected `Vec` but found `u32`".into(), - )), - CommandResponseValue::ValueU128(_) => Err(Error::InvalidResponse( - "expected `Vec` but found `u128`".into(), - )), - CommandResponseValue::Vector(value) => Ok(value), - } - } -} - -/// A response from a target device following a command -#[derive(Debug, Clone)] -pub struct CommandResponse { - pub resp: u8, - pub return_op: u8, - pub return_length: u16, - pub value: CommandResponseValue, - pub error: u8, - pub status: u8, -} - /// An established connection with a target device #[derive(Debug)] pub struct Connection {