From 808f23b7be0f159756d306de307e228cfe631e1a Mon Sep 17 00:00:00 2001 From: Fang-Pen Lin Date: Sun, 5 Jan 2025 20:43:49 -0800 Subject: [PATCH] Use iso8601 --- Cargo.lock | 64 +++++++++++++++++++++++++++++++++++++------- Cargo.toml | 2 +- src/api/processor.rs | 50 +++++++++++++++++----------------- src/main.rs | 38 +++++++++++++++++--------- 4 files changed, 105 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6db01e4..3815a01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,16 @@ dependencies = [ "thiserror 2.0.9", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "document-features" version = "0.2.10" @@ -1003,6 +1013,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -1051,6 +1067,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "prettyplease" version = "0.2.25" @@ -1215,7 +1237,7 @@ dependencies = [ "log", "serde", "serde_json", - "serde_millis", + "time", ] [[package]] @@ -1259,15 +1281,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_millis" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e2dc780ca5ee2c369d1d01d100270203c4ff923d2a4264812d723766434d00" -dependencies = [ - "serde", -] - [[package]] name = "shlex" version = "1.3.0" @@ -1409,6 +1422,37 @@ dependencies = [ "syn 2.0.94", ] +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "toml_datetime" version = "0.6.8" diff --git a/Cargo.toml b/Cargo.toml index b55cba2..11cd2aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,8 +30,8 @@ embassy-sync = "0.6.1" anyhow = "1.0.95" futures = "0.3.31" serde = { version = "1.0.217", features = ["derive"] } -serde_millis = "0.1.1" serde_json = "1.0.134" +time = { version = "0.3.37", features = ["std", "serde-human-readable"] } [[package.metadata.esp-idf-sys.extra_components]] remote_component = { name = "espressif/esp_tinyusb", version = "96cbb5b308f92d2493a0c714f097dcfc51add807", git = "https://github.com/LaunchPlatform/esp-usb.git", path = "device/esp_tinyusb" } diff --git a/src/api/processor.rs b/src/api/processor.rs index 1f18c5f..555407f 100644 --- a/src/api/processor.rs +++ b/src/api/processor.rs @@ -6,8 +6,9 @@ use esp_idf_svc::ping::Info; use serde::{Deserialize, Serialize}; use std::io::{Read, Seek}; use std::mem::MaybeUninit; -use std::time; -use std::time::Instant; +use std::time::SystemTime; +use time::serde::iso8601; +use time::OffsetDateTime; #[derive(Debug, Serialize, Deserialize, Clone)] #[serde(tag = "type")] @@ -22,21 +23,21 @@ pub enum Command { pub struct File { path: String, size: u64, - #[serde(with = "serde_millis")] - modified_at: Instant, - #[serde(with = "serde_millis")] - created_at: Instant, + #[serde(with = "iso8601")] + modified_at: OffsetDateTime, + #[serde(with = "iso8601")] + created_at: OffsetDateTime, is_dir: bool, } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct DeviceInfo { - version: String, - wifi_ip: String, - #[serde(with = "serde_millis")] - local_time: time::Instant, - disk_size: u64, - disk_usage: u64, + pub version: String, + pub wifi_ip: String, + #[serde(with = "iso8601")] + pub local_time: OffsetDateTime, + pub disk_size: u64, + pub disk_usage: u64, } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -72,13 +73,15 @@ pub struct CommandResponse<'a> { pub response: Response<'a>, } +pub type DeviceInfoProducer = Box anyhow::Result>; + pub struct Processor { - pub info_producer: Box anyhow::Result>, + pub device_info_producer: DeviceInfoProducer, } impl Processor { fn get_info(&self) -> anyhow::Result { - let result = (self.info_producer)(); + let result = (self.device_info_producer)(); if let Ok(device_info) = &result { log::info!("Get device info {device_info:#?}"); } @@ -151,8 +154,13 @@ impl Processor { } } -pub async fn process_events(mut client: WebSocketSession<'_>) { - let mut processor: Option> = None; +pub async fn process_events( + mut client: WebSocketSession<'_>, + device_info_producer: DeviceInfoProducer, +) { + let mut processor: Option> = Some(Box::new(Processor { + device_info_producer, + })); client.connect(); loop { @@ -165,15 +173,7 @@ pub async fn process_events(mut client: WebSocketSession<'_>) { .. } => { processor = Some(Box::new(Processor { - info_producer: Box::new(|| { - Ok(DeviceInfo { - version: "".to_string(), - wifi_ip: "".to_string(), - local_time: Instant::now(), - disk_size: 0, - disk_usage: 0, - }) - }), + device_info_producer: processor.map(|p| p.device_info_producer).unwrap(), })); } SessionEvent::ReceiveText { text } => { diff --git a/src/main.rs b/src/main.rs index e8e6c67..7a08d67 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,8 @@ mod api; mod usb; mod wifi; -use crate::api::websocket::{WebSocketSession, SessionEvent, ConnectionState}; +use crate::api::processor::{process_events, DeviceInfo, DeviceInfoProducer}; +use crate::api::websocket::{ConnectionState, SessionEvent, WebSocketSession}; use crate::usb::msc_device::MSCDevice; use crate::wifi::session::WifiSession; use embedded_svc::wifi::AuthMethod; @@ -11,21 +12,22 @@ use esp_idf_svc::hal::gpio::{PinDriver, Pull}; use esp_idf_svc::hal::prelude::Peripherals; use futures::executor::{LocalPool, LocalSpawner}; use futures::task::LocalSpawnExt; -use std::{thread, time}; -use crate::api::processor::process_events; +use std::rc::Rc; +use std::thread; +use std::time::Duration; +use time::OffsetDateTime; + +const PKG_NAME: &str = env!("CARGO_PKG_NAME"); +const VERSION: &str = env!("CARGO_PKG_VERSION"); const SSID: &str = env!("WIFI_SSID"); const PASSWORD: &str = env!("WIFI_PASS"); const API_ENDPOINT: &str = env!("API_ENDPOINT"); async fn run_async(spawner: LocalSpawner) -> Result<(), anyhow::Error> { - log::info!( - "Start {} - {}", - env!("CARGO_PKG_NAME"), - env!("CARGO_PKG_VERSION") - ); + log::info!("Start {} - {}", PKG_NAME, VERSION,); - let peripherals = Peripherals::take().expect("@@@ Take Peripherals failed"); + let peripherals = Peripherals::take()?; let mut wifi = WifiSession::new(SSID, PASSWORD, AuthMethod::WPA2Personal, peripherals.modem)?; wifi.connect().await?; log::info!("Connected wifi: {:#?}", wifi.get_ip_info()); @@ -36,14 +38,24 @@ async fn run_async(spawner: LocalSpawner) -> Result<(), anyhow::Error> { let mut button = PinDriver::input(peripherals.pins.gpio14)?; button.set_pull(Pull::Up)?; - let mut client = WebSocketSession::new(API_ENDPOINT, time::Duration::from_secs(30)); + let mut client = WebSocketSession::new(API_ENDPOINT, Duration::from_secs(30)); + + let device_info_producer: DeviceInfoProducer = Box::new(move || { + Ok(DeviceInfo { + version: VERSION.to_string(), + // TODO: maybe pass in Rc of wifi instead? + wifi_ip: wifi.get_ip_info().unwrap().ip.to_string(), + local_time: OffsetDateTime::now_utc(), + // TODO: + disk_size: 0, + disk_usage: 0, + }) + }); - // Asynchronously wait for GPIO events, allowing other tasks - // to run, or the core to sleep. button.wait_for_low().await?; log::info!("Button pressed!"); - spawner.spawn_local(process_events(client))?; + spawner.spawn_local(process_events(client, device_info_producer))?; loop { // Asynchronously wait for GPIO events, allowing other tasks