From 0d9f047e7f0bdea7029650c044ff86a051267371 Mon Sep 17 00:00:00 2001 From: Viktor Petersson Date: Mon, 14 Jul 2025 22:12:06 +0100 Subject: [PATCH 1/3] feat: add missing is_enabled and priority fields to CLI output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #240 - Add is_enabled and priority columns to Screens and Playlists formatters - Display boolean fields with visual indicators (✅ for true, ❌ for false) - Update test expectations to match new output format - Refactor boolean formatting logic to eliminate code duplication - Apply clippy fixes for improved code quality The v3 API documentation indicates these fields should be returned, but they were missing from the CLI table output. Now users can see the complete object information as specified in the API docs. --- build.rs | 2 +- src/api/asset.rs | 6 ++-- src/api/edge_app/app.rs | 9 +++-- src/api/edge_app/channel.rs | 3 +- src/api/edge_app/installation.rs | 10 +++--- src/api/edge_app/setting.rs | 24 +++++-------- src/api/edge_app/version.rs | 9 ++--- src/api/version.rs | 3 +- src/authentication.rs | 2 +- src/cli.rs | 9 +++-- src/commands/edge_app/app.rs | 2 +- src/commands/edge_app/instance_manifest.rs | 3 +- src/commands/edge_app/manifest.rs | 6 ++-- src/commands/edge_app/server.rs | 12 +++---- src/commands/edge_app/setting.rs | 2 +- src/commands/edge_app/utils.rs | 2 +- src/commands/ignorer.rs | 2 +- src/commands/mod.rs | 40 +++++++++++++++++----- src/commands/screen.rs | 14 ++++---- src/commands/serde_utils.rs | 9 ++--- 20 files changed, 83 insertions(+), 86 deletions(-) diff --git a/build.rs b/build.rs index d5608da..a9fc4bc 100644 --- a/build.rs +++ b/build.rs @@ -27,7 +27,7 @@ fn main() { }; fs::write( dest_path, - format!("pub const API_BASE_URL: &str = \"{}\";", api_server), + format!("pub const API_BASE_URL: &str = \"{api_server}\";"), ) .unwrap(); println!("cargo:rerun-if-changed=build.rs"); diff --git a/src/api/asset.rs b/src/api/asset.rs index 02ab1af..fc1486a 100644 --- a/src/api/asset.rs +++ b/src/api/asset.rs @@ -24,8 +24,7 @@ impl Api { Ok(serde_json::from_value(commands::get( &self.authentication, &format!( - "v4/assets?select=signature&app_id=eq.{}&app_revision=eq.{}&type=eq.edge-app-file", - app_id, revision + "v4/assets?select=signature&app_id=eq.{app_id}&app_revision=eq.{revision}&type=eq.edge-app-file" ), )?)?) } @@ -38,8 +37,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4/assets?select=status,processing_error,title&app_id=eq.{}&app_revision=eq.{}&status=neq.finished", - app_id, revision + "v4/assets?select=status,processing_error,title&app_id=eq.{app_id}&app_revision=eq.{revision}&status=neq.finished" ), )?; diff --git a/src/api/edge_app/app.rs b/src/api/edge_app/app.rs index cb26173..580df5b 100644 --- a/src/api/edge_app/app.rs +++ b/src/api/edge_app/app.rs @@ -53,7 +53,7 @@ impl Api { pub fn delete_app(&self, app_id: &str) -> Result<(), CommandError> { commands::delete( &self.authentication, - &format!("v4/edge-apps?id=eq.{}", app_id), + &format!("v4/edge-apps?id=eq.{app_id}"), )?; Ok(()) } @@ -61,7 +61,7 @@ impl Api { pub fn update_app(&self, app_id: &str, name: &str) -> Result<(), CommandError> { commands::patch( &self.authentication, - &format!("v4/edge-apps?select=name&id=eq.{}", app_id), + &format!("v4/edge-apps?select=name&id=eq.{app_id}"), &json!({ "name": name }), )?; Ok(()) @@ -70,14 +70,13 @@ impl Api { pub fn get_app(&self, app_id: &str) -> Result { let response = commands::get( &self.authentication, - &format!("v4/edge-apps?select=name&id=eq.{}", app_id), + &format!("v4/edge-apps?select=name&id=eq.{app_id}"), )?; let apps = serde_json::from_value::>(response)?; if apps.is_empty() { Err(CommandError::AppNotFound(format!( - "Edge app with ID '{}' not found.", - app_id + "Edge app with ID '{app_id}' not found." ))) } else { Ok(apps[0].clone()) diff --git a/src/api/edge_app/channel.rs b/src/api/edge_app/channel.rs index 5041865..1da842a 100644 --- a/src/api/edge_app/channel.rs +++ b/src/api/edge_app/channel.rs @@ -16,8 +16,7 @@ impl Api { let response = commands::patch( &self.authentication, &format!( - "v4/edge-apps/channels?select=channel,app_revision&channel=eq.{}&app_id=eq.{}", - channel, app_id + "v4/edge-apps/channels?select=channel,app_revision&channel=eq.{channel}&app_id=eq.{app_id}" ), &json!( { diff --git a/src/api/edge_app/installation.rs b/src/api/edge_app/installation.rs index 44065b2..d5a92b7 100644 --- a/src/api/edge_app/installation.rs +++ b/src/api/edge_app/installation.rs @@ -21,8 +21,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4.1/edge-apps/installations?select=name&id=eq.{}", - installation_id + "v4.1/edge-apps/installations?select=name&id=eq.{installation_id}" ), )?; @@ -43,8 +42,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4/edge-apps/installations?select=id,name&app_id=eq.{}", - app_id + "v4/edge-apps/installations?select=id,name&app_id=eq.{app_id}" ), )?; @@ -56,7 +54,7 @@ impl Api { pub fn delete_installation(&self, installation_id: &str) -> Result<(), CommandError> { commands::delete( &self.authentication, - &format!("v4.1/edge-apps/installations?id=eq.{}", installation_id), + &format!("v4.1/edge-apps/installations?id=eq.{installation_id}"), )?; Ok(()) } @@ -71,7 +69,7 @@ impl Api { }); commands::patch( &self.authentication, - &format!("v4.1/edge-apps/installations?id=eq.{}", installation_id), + &format!("v4.1/edge-apps/installations?id=eq.{installation_id}"), &payload, )?; Ok(()) diff --git a/src/api/edge_app/setting.rs b/src/api/edge_app/setting.rs index 71ea06f..48ad2e4 100644 --- a/src/api/edge_app/setting.rs +++ b/src/api/edge_app/setting.rs @@ -173,8 +173,7 @@ where match SettingType::from_str(&s.to_lowercase()) { Ok(setting_type) => Ok(setting_type), Err(_) => Err(serde::de::Error::custom(format!( - "Setting type should be one of the following:\n{}", - valid_setting_types + "Setting type should be one of the following:\n{valid_setting_types}" ))), } } @@ -212,8 +211,7 @@ impl Api { Ok(deserialize_settings_from_array(commands::get( &self.authentication, &format!( - "v4.1/edge-apps/settings?select=name,type,default_value,optional,title,help_text&app_id=eq.{}&order=name.asc", - app_id, + "v4.1/edge-apps/settings?select=name,type,default_value,optional,title,help_text&app_id=eq.{app_id}&order=name.asc", ), )?)?) } @@ -222,8 +220,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4.1/edge-apps/settings?select=is_global&app_id=eq.{}&name=eq.{}", - app_id, setting_key, + "v4.1/edge-apps/settings?select=is_global&app_id=eq.{app_id}&name=eq.{setting_key}", ), )?; @@ -247,8 +244,7 @@ impl Api { // TODO: test values are returned properly when there are several installations. Most likely need to feed installation_id to the request. // installation_id=is.null or installation_id=eq.smth let app_settings: Vec> = serde_json::from_value(commands::get(&self.authentication, - &format!("v4.1/edge-apps/settings?select=name,type,default_value,optional,title,help_text,edge_app_setting_values(value)&app_id=eq.{}&order=name.asc", - app_id, + &format!("v4.1/edge-apps/settings?select=name,type,default_value,optional,title,help_text,edge_app_setting_values(value)&app_id=eq.{app_id}&order=name.asc", ))?)?; Ok(EdgeAppSettings::new(serde_json::to_value(app_settings)?)) @@ -262,8 +258,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4.1/edge-apps/settings?select=name,type,edge_app_setting_values(value)&app_id=eq.{}&edge_app_setting_values.app_id=eq.{}&name=eq.{}", - app_id, app_id, setting_key + "v4.1/edge-apps/settings?select=name,type,edge_app_setting_values(value)&app_id=eq.{app_id}&edge_app_setting_values.app_id=eq.{app_id}&name=eq.{setting_key}" ), )?; let settings = serde_json::from_value::>(response)?; @@ -282,8 +277,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4.1/edge-apps/settings?select=name,type,edge_app_setting_values(value)&edge_app_setting_values.installation_id=eq.{}&name=eq.{}&app_id=eq.{}", - installation_id, setting_key, app_id + "v4.1/edge-apps/settings?select=name,type,edge_app_setting_values(value)&edge_app_setting_values.installation_id=eq.{installation_id}&name=eq.{setting_key}&app_id=eq.{app_id}" ), )?; @@ -388,8 +382,7 @@ impl Api { commands::patch( &self.authentication, &format!( - "v4.1/edge-apps/settings/values?app_id=eq.{}&name=eq.{}&installation_id=is.null", - app_id, setting_key + "v4.1/edge-apps/settings/values?app_id=eq.{app_id}&name=eq.{setting_key}&installation_id=is.null" ), &json!({ "value": setting_value, @@ -408,8 +401,7 @@ impl Api { commands::patch( &self.authentication, &format!( - "v4.1/edge-apps/settings/values?installation_id=eq.{}&name=eq.{}", - installation_id, setting_key + "v4.1/edge-apps/settings/values?installation_id=eq.{installation_id}&name=eq.{setting_key}" ), &json!({ "value": setting_value, diff --git a/src/api/edge_app/version.rs b/src/api/edge_app/version.rs index 53af89d..5c8e7a4 100644 --- a/src/api/edge_app/version.rs +++ b/src/api/edge_app/version.rs @@ -14,8 +14,7 @@ impl Api { let get_response = commands::get( &self.authentication, &format!( - "v4/edge-apps/versions?select=revision&app_id=eq.{}&revision=eq.{}", - app_id, revision + "v4/edge-apps/versions?select=revision&app_id=eq.{app_id}&revision=eq.{revision}" ), )?; let version = @@ -54,8 +53,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4/edge-apps/versions?select=file_tree&app_id=eq.{}&revision=eq.{}", - app_id, revision + "v4/edge-apps/versions?select=file_tree&app_id=eq.{app_id}&revision=eq.{revision}" ), )?; @@ -75,8 +73,7 @@ impl Api { commands::patch( &self.authentication, &format!( - "v4/edge-apps/versions?app_id=eq.{}&revision=eq.{}", - app_id, revision + "v4/edge-apps/versions?app_id=eq.{app_id}&revision=eq.{revision}" ), &json!({"published": true}), )?; diff --git a/src/api/version.rs b/src/api/version.rs index 5ef379c..aa7c087 100644 --- a/src/api/version.rs +++ b/src/api/version.rs @@ -30,8 +30,7 @@ impl Api { let response = commands::get( &self.authentication, &format!( - "v4.1/edge-apps/versions?select=user_version,description,icon,author,homepage_url,revision,ready_signal&app_id=eq.{}&order=revision.desc&limit=1", - app_id + "v4.1/edge-apps/versions?select=user_version,description,icon,author,homepage_url,revision,ready_signal&app_id=eq.{app_id}&order=revision.desc&limit=1" ), )?; diff --git a/src/authentication.rs b/src/authentication.rs index fd1ef03..a3060f4 100644 --- a/src/authentication.rs +++ b/src/authentication.rs @@ -130,7 +130,7 @@ pub fn verify_and_store_token( fn verify_token(token: &str, api_url: &str) -> anyhow::Result<(), AuthenticationError> { // Using uuid of non existing playlist. If we get 404 it means we authenticated successfully. - let url = format!("{}/v3/groups/11CF9Z3GZR0005XXKH00F8V20R/", api_url); + let url = format!("{api_url}/v3/groups/11CF9Z3GZR0005XXKH00F8V20R/"); let secret = format!("Token {token}"); let client = reqwest::blocking::Client::builder().build()?; diff --git a/src/cli.rs b/src/cli.rs index 93236cb..141c6b6 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -612,7 +612,7 @@ pub fn handle_cli_playlist_command(command: &PlaylistCommands) { match playlist_file { Ok(playlist) => { let pretty_playlist_file = serde_json::to_string_pretty(&playlist).unwrap(); - println!("{}", pretty_playlist_file); + println!("{pretty_playlist_file}"); } Err(e) => { eprintln!("Error occurred when getting playlist: {e:?}") @@ -864,8 +864,7 @@ pub fn handle_cli_edge_app_command(command: &EdgeAppCommands) { } => match edge_app_command.deploy(path.clone(), *delete_missing_settings) { Ok(revision) => { println!( - "Edge app successfully deployed. Revision: {revision}.", - revision = revision + "Edge app successfully deployed. Revision: {revision}." ); } Err(e) => { @@ -883,7 +882,7 @@ pub fn handle_cli_edge_app_command(command: &EdgeAppCommands) { println!("Edge app setting successfully set."); } Err(e) => { - eprintln!("Failed to set edge app setting: {}", e); + eprintln!("Failed to set edge app setting: {e}"); std::process::exit(1); } } @@ -1136,7 +1135,7 @@ pub fn handle_cli_edge_app_command(command: &EdgeAppCommands) { } }, Err(e) => { - eprintln!("Failed to delete edge app instance. {:?}", e); + eprintln!("Failed to delete edge app instance. {e:?}"); std::process::exit(1); } }; diff --git a/src/commands/edge_app/app.rs b/src/commands/edge_app/app.rs index 19f2ea5..4e125e3 100644 --- a/src/commands/edge_app/app.rs +++ b/src/commands/edge_app/app.rs @@ -465,7 +465,7 @@ impl EdgeAppCommand { } let prompt = format!("It seems like the setting \"{}\" is absent in the YAML file, but it exists on the server. If you wish to skip deletion, you can leave the input blank. Warning, deleting the setting will drop all the associated values. To proceed with deletion, please confirm the setting name by writing it down: ", setting.name); - println!("{}", prompt); + println!("{prompt}"); io::stdin() .read_line(&mut input_name) .expect("Failed to read input"); diff --git a/src/commands/edge_app/instance_manifest.rs b/src/commands/edge_app/instance_manifest.rs index 3d6feee..13b415c 100644 --- a/src/commands/edge_app/instance_manifest.rs +++ b/src/commands/edge_app/instance_manifest.rs @@ -68,8 +68,7 @@ where match s.as_str() { INSTANCE_MANIFEST_VERSION => Ok(s), invalid => Err(serde::de::Error::custom(format!( - "Invalid syntax: {}. Only 'instance_v1' is accepted.", - invalid + "Invalid syntax: {invalid}. Only 'instance_v1' is accepted." ))), } } diff --git a/src/commands/edge_app/manifest.rs b/src/commands/edge_app/manifest.rs index 325fbea..c40c1a2 100644 --- a/src/commands/edge_app/manifest.rs +++ b/src/commands/edge_app/manifest.rs @@ -141,8 +141,7 @@ where "basic" => Ok(AuthType::Basic), "bearer" => Ok(AuthType::Bearer), _ => Err(serde::de::Error::custom(format!( - "Invalid auth type: {}", - s + "Invalid auth type: {s}" ))), } } @@ -155,8 +154,7 @@ where match s.as_str() { MANIFEST_VERSION => Ok(s), invalid => Err(serde::de::Error::custom(format!( - "Invalid syntax: {}. Only 'manifest_v1' is accepted.", - invalid + "Invalid syntax: {invalid}. Only 'manifest_v1' is accepted." ))), } } diff --git a/src/commands/edge_app/server.rs b/src/commands/edge_app/server.rs index 681431e..b645f2c 100644 --- a/src/commands/edge_app/server.rs +++ b/src/commands/edge_app/server.rs @@ -80,7 +80,7 @@ pub async fn run_server( tokio::task::spawn(server_future); - Ok(format!("http://{}/edge/1", addr)) + Ok(format!("http://{addr}/edge/1")) } #[derive(Debug)] @@ -134,7 +134,7 @@ async fn generate_content( let data: MockData = match serde_yaml::from_str(&content) { Ok(data) => data, Err(e) => { - eprintln!("Failed to parse mock data: {}", e); + eprintln!("Failed to parse mock data: {e}"); return Err(warp::reject::not_found()); } }; @@ -202,19 +202,19 @@ fn format_section(name: &str, items: &[(String, Value)]) -> String { let content = items .iter() .map(|(k, v)| match v { - Value::Str(s) => format!(" \"{}\": \"{}\"", k, s), + Value::Str(s) => format!(" \"{k}\": \"{s}\""), Value::Array(arr) => format!( " \"{}\": [{}]", k, arr.iter() - .map(|item| format!("\"{}\"", item)) + .map(|item| format!("\"{item}\"")) .collect::>() .join(", ") ), }) .collect::>() .join(",\n"); - format!(" {}: {{\n{}\n }}", name, content) + format!(" {name}: {{\n{content}\n }}") } impl EdgeAppCommand { @@ -246,7 +246,7 @@ impl EdgeAppCommand { "{}/index.html", address_shared.lock().unwrap().as_ref().unwrap() )) { - eprintln!("{}", e); + eprintln!("{e}"); } loop { diff --git a/src/commands/edge_app/setting.rs b/src/commands/edge_app/setting.rs index 92976a5..11284bd 100644 --- a/src/commands/edge_app/setting.rs +++ b/src/commands/edge_app/setting.rs @@ -98,7 +98,7 @@ impl EdgeAppCommand { if setting.edge_app_setting_values.len() == 1 && setting.edge_app_setting_values[0].get("value").unwrap() == setting_value { - println!("Setting value is already set to {}", setting_value); + println!("Setting value is already set to {setting_value}"); return Ok(()); } diff --git a/src/commands/edge_app/utils.rs b/src/commands/edge_app/utils.rs index 01602d2..851258c 100644 --- a/src/commands/edge_app/utils.rs +++ b/src/commands/edge_app/utils.rs @@ -137,7 +137,7 @@ pub fn collect_paths_for_upload(path: &Path) -> Result, Command let mut files = Vec::new(); let ignore = Ignorer::new(path).map_err(|e| { - CommandError::IgnoreError(format!("Failed to initialize ignore module: {}", e)) + CommandError::IgnoreError(format!("Failed to initialize ignore module: {e}")) })?; for entry in WalkDir::new(path) diff --git a/src/commands/ignorer.rs b/src/commands/ignorer.rs index 6942f3e..8bbe698 100644 --- a/src/commands/ignorer.rs +++ b/src/commands/ignorer.rs @@ -23,7 +23,7 @@ impl Ignorer { } else if pattern.contains('*') { // Convert wildcard '*' to regex '.*' let converted = pattern.replace('.', r"\.").replace('*', r".*"); - patterns.push(format!("^{}$", converted)); + patterns.push(format!("^{converted}$")); } else { patterns.push(format!("^{}$", regex::escape(pattern))); } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 8fe758e..d980ccb 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -430,11 +430,21 @@ impl FormatterValue for Screens { impl Formatter for Screens { fn format(&self, output_type: OutputType) -> String { + fn format_boolean_field(value: &serde_json::Value) -> Cell { + if value.as_bool().unwrap_or(false) { + cell!(c -> "✅") + } else { + cell!(c -> "❌") + } + } + format_value( output_type, vec![ "Id", "Name", + "Enabled", + "Priority", "Hardware Version", "In Sync", "Last Ping", @@ -443,6 +453,8 @@ impl Formatter for Screens { vec![ "id", "name", + "is_enabled", + "priority", "hardware_version", "in_sync", "last_ping", @@ -450,12 +462,8 @@ impl Formatter for Screens { ], self, Some(|field: &str, value: &serde_json::Value| { - if field.eq("in_sync") { - if value.as_bool().unwrap_or(false) { - cell!(c -> "✅") - } else { - cell!(c -> "❌") - } + if field.eq("is_enabled") || field.eq("priority") || field.eq("in_sync") { + format_boolean_field(value) } else if field.eq("uptime") { let uptime = if let Some(uptime) = value.as_u64() { indicatif::HumanDuration(Duration::new(uptime, 0)).to_string() @@ -490,12 +498,26 @@ impl FormatterValue for Playlists { impl Formatter for Playlists { fn format(&self, output_type: OutputType) -> String { + fn format_boolean_field(value: &serde_json::Value) -> Cell { + if value.as_bool().unwrap_or(false) { + cell!(c -> "✅") + } else { + cell!(c -> "❌") + } + } + format_value( output_type, - vec!["Id", "Title"], - vec!["id", "title"], + vec!["Id", "Title", "Enabled", "Priority"], + vec!["id", "title", "is_enabled", "priority"], self, - None:: Cell>, + Some(|field: &str, value: &serde_json::Value| { + if field.eq("is_enabled") || field.eq("priority") { + format_boolean_field(value) + } else { + Cell::new(value.as_str().unwrap_or("N/A")) + } + }), ) } } diff --git a/src/commands/screen.rs b/src/commands/screen.rs index 21cce78..9ca7344 100644 --- a/src/commands/screen.rs +++ b/src/commands/screen.rs @@ -179,13 +179,13 @@ mod tests { let screen = Screens::new(serde_json::from_str("[{\"id\":\"017a5104-524b-33d8-8026-9087b59e7eb5\",\"team_id\":\"016343c2-82b8-0000-a121-e30f1035875e\",\"created_at\":\"2021-06-28T05:07:55+00:00\",\"name\":\"Renat's integrated wired NM\",\"is_enabled\":true,\"coords\":[55.22931, 48.90429],\"last_ping\":\"2021-08-25T06:17:20.728+00:00\",\"last_ip\":null,\"local_ip\":\"192.168.1.146\",\"mac\":\"b8:27:eb:d6:83:6f\",\"last_screenshot_time\":\"2021-08-25T06:09:04.399+00:00\",\"uptime\": 230728,\"load_avg\":\"0.14\",\"signal_strength\":null,\"interface\":\"eth0\",\"debug\":false,\"location\":\"Kamsko-Ust'inskiy rayon, Russia\",\"team\":\"016343c2-82b8-0000-a121-e30f1035875e\",\"timezone\":\"Europe/Moscow\",\"type\":\"hardware\",\"hostname\":\"srly-4shnfrdc5cd2p0p\",\"ws_open\":false,\"status\":\"Offline\",\"last_screenshot\":\"https://us-assets.screenlyapp.com/01CD1W50NR000A28F31W83B1TY/screenshots/01F98G8MJB6FC809MGGYTSWZNN/5267668e6db35498e61b83d4c702dbe8\",\"in_sync\":false,\"software_version\":\"Screenly 2 Player\",\"hardware_version\":\"Raspberry Pi 3B\",\"config\":{\"hdmi_mode\": 34, \"hdmi_boost\": 2, \"hdmi_drive\": 0, \"hdmi_group\": 0, \"verify_ssl\": true, \"audio_output\": \"hdmi\", \"hdmi_timings\": \"\", \"overscan_top\": 0, \"overscan_left\": 0, \"use_composite\": false, \"display_rotate\": 0, \"overscan_right\": 0, \"overscan_scale\": 0, \"overscan_bottom\": 0, \"disable_overscan\": 0, \"shuffle_playlist\": false, \"framebuffer_width\": 0, \"use_composite_pal\": false, \"framebuffer_height\": 0, \"hdmi_force_hotplug\": true, \"use_composite_ntsc\": false, \"hdmi_pixel_encoding\": 0, \"play_history_enabled\": false}}, {\"id\":\"017a5104-524b-33d8-8026-9087b59e7eb6\",\"team_id\":\"016343c2-82b8-0000-a121-e30f1035875d\",\"created_at\":\"2020-06-28T05:07:55+00:00\",\"name\":\"Not Renat's integrated wired NM\",\"is_enabled\":true,\"coords\":[55.22931, 48.90429],\"last_ping\":\"2020-08-25T06:17:20.728+00:00\",\"last_ip\":null,\"local_ip\":\"192.168.1.146\",\"mac\":\"b8:27:eb:d6:83:6f\",\"last_screenshot_time\":\"2021-08-25T06:09:04.399+00:00\",\"uptime\":230728,\"load_avg\":\"0.14\",\"signal_strength\":null,\"interface\":\"eth0\",\"debug\":false,\"location\":\"Kamsko-Ust'inskiy rayon, Russia\",\"team\":\"016343c2-82b8-0000-a121-e30f1035875e\",\"timezone\":\"Europe/Moscow\",\"type\":\"hardware\",\"hostname\":\"srly-4shnfrdc5cd2p0p\",\"ws_open\":false,\"status\":\"Offline\",\"last_screenshot\":\"https://us-assets.screenlyapp.com/01CD1W50NR000A28F31W83B1TY/screenshots/01F98G8MJB6FC809MGGYTSWZNN/5267668e6db35498e61b83d4c702dbe8\",\"in_sync\":false,\"software_version\":\"Screenly 2 Player\",\"hardware_version\":\"Raspberry Pi 3B\",\"config\":{\"hdmi_mode\": 34, \"hdmi_boost\": 2, \"hdmi_drive\": 0, \"hdmi_group\": 0, \"verify_ssl\": true, \"audio_output\": \"hdmi\", \"hdmi_timings\": \"\", \"overscan_top\": 0, \"overscan_left\": 0, \"use_composite\": false, \"display_rotate\": 0, \"overscan_right\": 0, \"overscan_scale\": 0, \"overscan_bottom\": 0, \"disable_overscan\": 0, \"shuffle_playlist\": false, \"framebuffer_width\": 0, \"use_composite_pal\": false, \"framebuffer_height\": 0, \"hdmi_force_hotplug\": true, \"use_composite_ntsc\": false, \"hdmi_pixel_encoding\": 0, \"play_history_enabled\": false}}]").unwrap()); println!("{}", screen.format(OutputType::HumanReadable)); let expected_output = - "+--------------------------------------+---------------------------------+------------------+---------+-------------------------------+--------+\n\ -| Id | Name | Hardware Version | In Sync | Last Ping | Uptime |\n\ -+--------------------------------------+---------------------------------+------------------+---------+-------------------------------+--------+\n\ -| 017a5104-524b-33d8-8026-9087b59e7eb5 | Renat's integrated wired NM | Raspberry Pi 3B | ❌ | 2021-08-25T06:17:20.728+00:00 | 3 days |\n\ -+--------------------------------------+---------------------------------+------------------+---------+-------------------------------+--------+\n\ -| 017a5104-524b-33d8-8026-9087b59e7eb6 | Not Renat's integrated wired NM | Raspberry Pi 3B | ❌ | 2020-08-25T06:17:20.728+00:00 | 3 days |\n\ -+--------------------------------------+---------------------------------+------------------+---------+-------------------------------+--------+\n"; + "+--------------------------------------+---------------------------------+---------+----------+------------------+---------+-------------------------------+--------+\n\ +| Id | Name | Enabled | Priority | Hardware Version | In Sync | Last Ping | Uptime |\n\ ++--------------------------------------+---------------------------------+---------+----------+------------------+---------+-------------------------------+--------+\n\ +| 017a5104-524b-33d8-8026-9087b59e7eb5 | Renat's integrated wired NM | ✅ | ❌ | Raspberry Pi 3B | ❌ | 2021-08-25T06:17:20.728+00:00 | 3 days |\n\ ++--------------------------------------+---------------------------------+---------+----------+------------------+---------+-------------------------------+--------+\n\ +| 017a5104-524b-33d8-8026-9087b59e7eb6 | Not Renat's integrated wired NM | ✅ | ❌ | Raspberry Pi 3B | ❌ | 2020-08-25T06:17:20.728+00:00 | 3 days |\n\ ++--------------------------------------+---------------------------------+---------+----------+------------------+---------+-------------------------------+--------+\n"; assert_eq!(screen.format(OutputType::HumanReadable), expected_output); } diff --git a/src/commands/serde_utils.rs b/src/commands/serde_utils.rs index b4b7db9..9bb7092 100644 --- a/src/commands/serde_utils.rs +++ b/src/commands/serde_utils.rs @@ -15,8 +15,7 @@ where Some(ref s) if s.trim().is_empty() => { if error_on_empty { Err(serde::de::Error::custom(format!( - "Field \"{}\" cannot be empty", - field_name + "Field \"{field_name}\" cannot be empty" ))) } else { Ok(None) @@ -36,8 +35,7 @@ where { if value.trim().is_empty() { Err(serde::ser::Error::custom(format!( - "Field \"{}\" cannot be empty", - field_name + "Field \"{field_name}\" cannot be empty" ))) } else { serializer.serialize_str(value) @@ -56,8 +54,7 @@ where if s.trim().is_empty() && error_on_empty { Err(serde::de::Error::custom(format!( - "Field \"{}\" cannot be empty", - field_name + "Field \"{field_name}\" cannot be empty" ))) } else { Ok(s) From 68bd65f832a09b0b1b6ba720badd4815877eadfb Mon Sep 17 00:00:00 2001 From: Sergey Borovkov Date: Wed, 6 Aug 2025 21:33:12 +0400 Subject: [PATCH 2/3] Format --- rustfmt.toml | 6 +++ src/api/asset.rs | 4 +- src/api/edge_app/app.rs | 5 +-- src/api/edge_app/channel.rs | 7 ++-- src/api/edge_app/installation.rs | 14 +++---- src/api/edge_app/setting.rs | 14 +++---- src/api/edge_app/version.rs | 17 ++++---- src/api/version.rs | 4 +- src/authentication.rs | 3 +- src/cli.rs | 10 ++--- src/commands/asset.rs | 25 +++++------ src/commands/edge_app/app.rs | 48 ++++++++++------------ src/commands/edge_app/instance.rs | 18 ++++---- src/commands/edge_app/instance_manifest.rs | 14 +++---- src/commands/edge_app/manifest.rs | 16 +++----- src/commands/edge_app/server.rs | 21 +++++----- src/commands/edge_app/setting.rs | 18 ++++---- src/commands/edge_app/test_utils.rs | 10 ++--- src/commands/edge_app/utils.rs | 27 ++++++------ src/commands/ignorer.rs | 7 +++- src/commands/mod.rs | 16 ++++---- src/commands/playlist.rs | 10 +++-- src/commands/screen.rs | 19 ++++----- src/main.rs | 5 ++- src/signature.rs | 19 +++++---- 25 files changed, 169 insertions(+), 188 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..26d1277 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,6 @@ +group_imports = "StdExternalCrate" +imports_granularity = "Module" +unstable_features = true +format_generated_files = false + +ignore = ["furiousfilter/**"] diff --git a/src/api/asset.rs b/src/api/asset.rs index fc1486a..1588a92 100644 --- a/src/api/asset.rs +++ b/src/api/asset.rs @@ -1,9 +1,9 @@ +use serde::{Deserialize, Serialize}; + use crate::api::Api; use crate::commands; use crate::commands::CommandError; -use serde::{Deserialize, Serialize}; - #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct AssetSignature { pub(crate) signature: String, diff --git a/src/api/edge_app/app.rs b/src/api/edge_app/app.rs index 580df5b..26cf83b 100644 --- a/src/api/edge_app/app.rs +++ b/src/api/edge_app/app.rs @@ -1,12 +1,11 @@ use log::debug; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; use crate::api::Api; use crate::commands; use crate::commands::CommandError; -use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; - #[derive(Debug)] pub struct EdgeApps { pub value: serde_json::Value, diff --git a/src/api/edge_app/channel.rs b/src/api/edge_app/channel.rs index 1da842a..601c224 100644 --- a/src/api/edge_app/channel.rs +++ b/src/api/edge_app/channel.rs @@ -1,11 +1,10 @@ +use serde::Deserialize; +use serde_json::json; + use crate::api::Api; use crate::commands; use crate::commands::CommandError; -use serde_json::json; - -use serde::Deserialize; - impl Api { pub fn update_channel( &self, diff --git a/src/api/edge_app/installation.rs b/src/api/edge_app/installation.rs index d5a92b7..0671f46 100644 --- a/src/api/edge_app/installation.rs +++ b/src/api/edge_app/installation.rs @@ -1,10 +1,10 @@ +use serde::{Deserialize, Serialize}; +use serde_json::json; + use crate::api::Api; use crate::commands; use crate::commands::CommandError; -use serde::{Deserialize, Serialize}; -use serde_json::json; - #[derive(Debug)] pub struct EdgeAppInstances { pub value: serde_json::Value, @@ -20,9 +20,7 @@ impl Api { pub fn get_instance_name(&self, installation_id: &str) -> Result { let response = commands::get( &self.authentication, - &format!( - "v4.1/edge-apps/installations?select=name&id=eq.{installation_id}" - ), + &format!("v4.1/edge-apps/installations?select=name&id=eq.{installation_id}"), )?; #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] @@ -41,9 +39,7 @@ impl Api { pub fn list_installations(&self, app_id: &str) -> Result { let response = commands::get( &self.authentication, - &format!( - "v4/edge-apps/installations?select=id,name&app_id=eq.{app_id}" - ), + &format!("v4/edge-apps/installations?select=id,name&app_id=eq.{app_id}"), )?; let instances = EdgeAppInstances::new(response); diff --git a/src/api/edge_app/setting.rs b/src/api/edge_app/setting.rs index 48ad2e4..3233bc5 100644 --- a/src/api/edge_app/setting.rs +++ b/src/api/edge_app/setting.rs @@ -1,19 +1,17 @@ -use crate::commands; -use crate::commands::CommandError; -use crate::{api::Api, commands::EdgeAppSettings}; - -use log::debug; -use serde_json::{json, Value}; use std::collections::HashMap; use std::ops::Not; use std::str::FromStr; -use serde::Deserializer; +use log::debug; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_json::{json, Value}; use strum::IntoEnumIterator; use strum_macros::{Display, EnumIter, EnumString}; +use crate::api::Api; +use crate::commands; use crate::commands::serde_utils::{deserialize_string_field, serialize_non_empty_string_field}; -use serde::{Deserialize, Serialize}; +use crate::commands::{CommandError, EdgeAppSettings}; #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct SettingValue { diff --git a/src/api/edge_app/version.rs b/src/api/edge_app/version.rs index 5c8e7a4..551a997 100644 --- a/src/api/edge_app/version.rs +++ b/src/api/edge_app/version.rs @@ -1,13 +1,12 @@ -use crate::api::Api; -use crate::commands; -use crate::commands::CommandError; - -use log::debug; -use serde_json::Value; use std::collections::HashMap; +use log::debug; use serde::Deserialize; -use serde_json::json; +use serde_json::{json, Value}; + +use crate::api::Api; +use crate::commands; +use crate::commands::CommandError; impl Api { pub fn version_exists(&self, app_id: &str, revision: u32) -> Result { @@ -72,9 +71,7 @@ impl Api { pub fn publish_version(&self, app_id: &str, revision: u32) -> Result<(), CommandError> { commands::patch( &self.authentication, - &format!( - "v4/edge-apps/versions?app_id=eq.{app_id}&revision=eq.{revision}" - ), + &format!("v4/edge-apps/versions?app_id=eq.{app_id}&revision=eq.{revision}"), &json!({"published": true}), )?; Ok(()) diff --git a/src/api/version.rs b/src/api/version.rs index aa7c087..6972f25 100644 --- a/src/api/version.rs +++ b/src/api/version.rs @@ -1,9 +1,9 @@ +use serde::{Deserialize, Serialize}; + use crate::api::Api; use crate::commands; use crate::commands::CommandError; -use serde::{Deserialize, Serialize}; - #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct EdgeAppVersion { #[serde(default)] diff --git a/src/authentication.rs b/src/authentication.rs index a3060f4..ae14e67 100644 --- a/src/authentication.rs +++ b/src/authentication.rs @@ -153,7 +153,8 @@ mod tests { use envtestkit::lock::lock_test; use envtestkit::set_env; - use httpmock::{Method::GET, MockServer}; + use httpmock::Method::GET; + use httpmock::MockServer; use simple_logger::SimpleLogger; use tempfile::tempdir; diff --git a/src/cli.rs b/src/cli.rs index 141c6b6..fd7621c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -863,9 +863,7 @@ pub fn handle_cli_edge_app_command(command: &EdgeAppCommands) { delete_missing_settings, } => match edge_app_command.deploy(path.clone(), *delete_missing_settings) { Ok(revision) => { - println!( - "Edge app successfully deployed. Revision: {revision}." - ); + println!("Edge app successfully deployed. Revision: {revision}."); } Err(e) => { eprintln!("Failed to upload edge app: {e}."); @@ -1170,12 +1168,12 @@ pub fn handle_cli_edge_app_command(command: &EdgeAppCommands) { #[cfg(test)] mod tests { - use httpmock::{Method::GET, MockServer}; + use httpmock::Method::GET; + use httpmock::MockServer; use tempfile::tempdir; - use crate::authentication::Config; - use super::*; + use crate::authentication::Config; #[test] fn test_get_screen_name_should_return_correct_screen_name() { diff --git a/src/commands/asset.rs b/src/commands/asset.rs index 3a22924..50f4496 100644 --- a/src/commands/asset.rs +++ b/src/commands/asset.rs @@ -1,15 +1,16 @@ -use crate::authentication::Authentication; -use crate::commands; -use crate::commands::{Assets, CommandError}; +use std::collections::HashMap; +use std::fs::File; +use std::time::Duration; + use indicatif::{ProgressBar, ProgressStyle}; use log::{debug, info}; - use reqwest::header::HeaderMap; use reqwest::StatusCode; use serde_json::json; -use std::collections::HashMap; -use std::fs::File; -use std::time::Duration; + +use crate::authentication::Authentication; +use crate::commands; +use crate::commands::{Assets, CommandError}; pub struct AssetCommand { authentication: Authentication, @@ -159,16 +160,16 @@ impl AssetCommand { #[cfg(test)] mod tests { - use super::*; - use crate::authentication::Config; - use crate::commands::{Formatter, OutputType}; + use std::fs; use httpmock::Method::{DELETE, GET, PATCH, POST}; use httpmock::MockServer; - - use std::fs; use tempfile::tempdir; + use super::*; + use crate::authentication::Config; + use crate::commands::{Formatter, OutputType}; + #[test] fn test_list_assets_should_return_correct_asset_list() { let asset_list = json!([{ diff --git a/src/commands/edge_app/app.rs b/src/commands/edge_app/app.rs index 4e125e3..86b1e64 100644 --- a/src/commands/edge_app/app.rs +++ b/src/commands/edge_app/app.rs @@ -1,37 +1,33 @@ -use crate::api::edge_app::setting::{Setting, SettingType}; -use crate::api::version::EdgeAppVersion; -use crate::commands::edge_app::instance_manifest::InstanceManifest; -use crate::commands::edge_app::manifest::{EdgeAppManifest, Entrypoint}; -use crate::commands::edge_app::EdgeAppCommand; -use crate::commands::{CommandError, EdgeApps}; - -use indicatif::ProgressBar; -use log::debug; use std::collections::HashMap; -use std::{io, str, thread}; - -use reqwest::header::HeaderMap; -use reqwest::StatusCode; -use serde_json::json; -use serde_yaml; -use std::fs; use std::fs::File; use std::io::Write; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; +use std::time::{Duration, Instant}; +use std::{fs, io, str, thread}; +use indicatif::ProgressBar; +use log::debug; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; -use std::time::{Duration, Instant}; +use reqwest::header::HeaderMap; +use reqwest::StatusCode; +use serde_json::json; +use serde_yaml; +use crate::api::edge_app::setting::{Setting, SettingType}; +use crate::api::version::EdgeAppVersion; +use crate::commands::edge_app::instance_manifest::InstanceManifest; +use crate::commands::edge_app::manifest::{ + EdgeAppManifest, Entrypoint, EntrypointType, MANIFEST_VERSION, +}; use crate::commands::edge_app::utils::{ collect_paths_for_upload, detect_changed_files, detect_changed_settings, - ensure_edge_app_has_all_necessary_files, generate_file_tree, FileChanges, SettingChanges, + ensure_edge_app_has_all_necessary_files, generate_file_tree, + transform_edge_app_path_to_manifest, transform_instance_path_to_instance_manifest, FileChanges, + SettingChanges, }; - -use crate::commands::edge_app::utils::transform_edge_app_path_to_manifest; - -use crate::commands::edge_app::manifest::{EntrypointType, MANIFEST_VERSION}; -use crate::commands::edge_app::utils::transform_instance_path_to_instance_manifest; +use crate::commands::edge_app::EdgeAppCommand; +use crate::commands::{CommandError, EdgeApps}; // Edge apps commands impl EdgeAppCommand { @@ -610,18 +606,18 @@ impl EdgeAppCommand { #[cfg(test)] mod tests { - use super::*; use std::env; - use crate::commands::edge_app::manifest::MANIFEST_VERSION; use httpmock::Method::{DELETE, GET, PATCH, POST}; + use tempfile::tempdir; + use super::*; + use crate::commands::edge_app::manifest::MANIFEST_VERSION; use crate::commands::edge_app::test_utils::tests::{ create_edge_app_manifest_for_test, create_instance_manifest_for_test, prepare_edge_apps_test, }; use crate::commands::edge_app::utils::EdgeAppFile; - use tempfile::tempdir; #[test] fn test_edge_app_create_should_create_app_and_required_files() { diff --git a/src/commands/edge_app/instance.rs b/src/commands/edge_app/instance.rs index bd7ad66..8831331 100644 --- a/src/commands/edge_app/instance.rs +++ b/src/commands/edge_app/instance.rs @@ -1,12 +1,10 @@ -use super::EdgeAppCommand; +use std::path::Path; +use std::{fs, str}; +use super::EdgeAppCommand; use crate::commands::edge_app::instance_manifest::{InstanceManifest, INSTANCE_MANIFEST_VERSION}; use crate::commands::edge_app::utils::transform_instance_path_to_instance_manifest; use crate::commands::{CommandError, EdgeAppInstances}; -use std::str; - -use std::fs; -use std::path::Path; impl EdgeAppCommand { pub fn list_instances(&self, app_id: &str) -> Result { @@ -80,14 +78,12 @@ impl EdgeAppCommand { #[cfg(test)] mod tests { - use crate::commands::edge_app::instance_manifest::InstanceManifest; - use crate::commands::edge_app::manifest::EdgeAppManifest; - use crate::commands::edge_app::manifest::{Entrypoint, EntrypointType}; - use crate::commands::edge_app::test_utils::tests::prepare_edge_apps_test; use httpmock::Method::{DELETE, GET, PATCH, POST}; + use serde_json::{json, Value}; - use serde_json::json; - use serde_json::Value; + use crate::commands::edge_app::instance_manifest::InstanceManifest; + use crate::commands::edge_app::manifest::{EdgeAppManifest, Entrypoint, EntrypointType}; + use crate::commands::edge_app::test_utils::tests::prepare_edge_apps_test; #[test] fn test_instance_list_should_list_instances() { diff --git a/src/commands/edge_app/instance_manifest.rs b/src/commands/edge_app/instance_manifest.rs index 13b415c..8c138f9 100644 --- a/src/commands/edge_app/instance_manifest.rs +++ b/src/commands/edge_app/instance_manifest.rs @@ -1,20 +1,15 @@ -use std::{ - fs::{self, File}, - path::Path, -}; - +use std::fs::{self, File}; use std::io::Write; +use std::path::Path; use reqwest::Url; use serde::{Deserialize, Serialize}; - use serde_with::serde_as; +use crate::commands::edge_app::manifest::beautify_error_message; use crate::commands::serde_utils::{ deserialize_option_string_field, string_field_is_none_or_empty, }; - -use crate::commands::edge_app::manifest::beautify_error_message; use crate::commands::CommandError; pub const INSTANCE_MANIFEST_VERSION: &str = "instance_v1"; @@ -146,9 +141,10 @@ impl InstanceManifest { #[cfg(test)] mod tests { - use super::*; use tempfile::tempdir; + use super::*; + const INSTANCE_MANIFEST_FILENAME: &str = "instance.yml"; fn create_valid_manifest() -> InstanceManifest { diff --git a/src/commands/edge_app/manifest.rs b/src/commands/edge_app/manifest.rs index c40c1a2..712f2e5 100644 --- a/src/commands/edge_app/manifest.rs +++ b/src/commands/edge_app/manifest.rs @@ -1,21 +1,18 @@ -use crate::commands::CommandError; use std::collections::HashMap; - use std::fs; use std::fs::File; -use std::io::ErrorKind; -use std::io::Write; +use std::io::{ErrorKind, Write}; use std::path::Path; use serde::{Deserialize, Serialize}; use serde_json::json; +use super::manifest_auth::AuthType; use crate::api::edge_app::setting::{deserialize_settings, serialize_settings, Setting}; use crate::commands::serde_utils::{ deserialize_option_string_field, string_field_is_none_or_empty, }; - -use super::manifest_auth::AuthType; +use crate::commands::CommandError; pub const MANIFEST_VERSION: &str = "manifest_v1"; @@ -140,9 +137,7 @@ where match s.as_str() { "basic" => Ok(AuthType::Basic), "bearer" => Ok(AuthType::Bearer), - _ => Err(serde::de::Error::custom(format!( - "Invalid auth type: {s}" - ))), + _ => Err(serde::de::Error::custom(format!("Invalid auth type: {s}"))), } } @@ -329,9 +324,10 @@ pub fn beautify_error_message(error: &str) -> String { #[cfg(test)] mod tests { + use tempfile::tempdir; + use super::*; use crate::api::edge_app::setting::{Setting, SettingType}; - use tempfile::tempdir; fn create_test_manifest() -> EdgeAppManifest { EdgeAppManifest { diff --git a/src/commands/edge_app/server.rs b/src/commands/edge_app/server.rs index b645f2c..74f26d1 100644 --- a/src/commands/edge_app/server.rs +++ b/src/commands/edge_app/server.rs @@ -1,20 +1,20 @@ -use crate::api::edge_app::setting::SettingType; -use crate::commands::edge_app::manifest::EdgeAppManifest; -use crate::commands::edge_app::EdgeAppCommand; -use crate::commands::ignorer::Ignorer; -use crate::commands::CommandError; -use anyhow::Result; -use futures::future::{self, BoxFuture, FutureExt}; use std::collections::HashMap; +use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use std::{fs, str}; +use anyhow::Result; +use futures::future::{self, BoxFuture, FutureExt}; use serde::{Deserialize, Serialize}; - -use std::path::{Path, PathBuf}; use warp::reject::Reject; use warp::{Filter, Rejection, Reply}; +use crate::api::edge_app::setting::SettingType; +use crate::commands::edge_app::manifest::EdgeAppManifest; +use crate::commands::edge_app::EdgeAppCommand; +use crate::commands::ignorer::Ignorer; +use crate::commands::CommandError; + pub const MOCK_DATA_FILENAME: &str = "mock-data.yml"; #[derive(Debug, Clone, Deserialize, PartialEq)] @@ -328,10 +328,11 @@ impl EdgeAppCommand { #[cfg(test)] mod tests { - use super::*; use std::io::Write; + use tempfile::tempdir; + use super::*; use crate::api::edge_app::setting::{Setting, SettingType}; use crate::authentication::{Authentication, Config}; use crate::commands::edge_app::test_utils::tests::{ diff --git a/src/commands/edge_app/setting.rs b/src/commands/edge_app/setting.rs index 11284bd..bfbf3ef 100644 --- a/src/commands/edge_app/setting.rs +++ b/src/commands/edge_app/setting.rs @@ -1,13 +1,13 @@ -use crate::api::edge_app::setting::Setting; -use crate::commands::edge_app::EdgeAppCommand; -use crate::commands::{CommandError, EdgeAppSettings}; - -use log::debug; use std::collections::HashMap; use std::str; +use log::debug; use serde::{Deserialize, Serialize}; +use crate::api::edge_app::setting::Setting; +use crate::commands::edge_app::EdgeAppCommand; +use crate::commands::{CommandError, EdgeAppSettings}; + impl EdgeAppCommand { pub fn list_settings(&self, path: Option) -> Result { let app_id = self.get_app_id(path)?; @@ -155,14 +155,14 @@ impl EdgeAppCommand { #[cfg(test)] mod tests { - use super::*; - use serde_json::{json, Value}; use std::env; - use crate::api::edge_app::setting::SettingType; + use httpmock::Method::{GET, PATCH, POST}; + use serde_json::{json, Value}; + use super::*; + use crate::api::edge_app::setting::SettingType; use crate::commands::edge_app::test_utils::tests::prepare_edge_apps_test; - use httpmock::Method::{GET, PATCH, POST}; #[test] fn test_list_settings_should_send_correct_request() { diff --git a/src/commands/edge_app/test_utils.rs b/src/commands/edge_app/test_utils.rs index eaec855..ec8d1ed 100644 --- a/src/commands/edge_app/test_utils.rs +++ b/src/commands/edge_app/test_utils.rs @@ -1,10 +1,10 @@ #[cfg(test)] pub mod tests { - use crate::authentication::Config; - use tempfile::TempDir; + use httpmock::MockServer; + use tempfile::{tempdir, TempDir}; use crate::api::edge_app::setting::Setting; - use crate::authentication::Authentication; + use crate::authentication::{Authentication, Config}; use crate::commands::edge_app::instance_manifest::{ InstanceManifest, INSTANCE_MANIFEST_VERSION, }; @@ -13,10 +13,6 @@ pub mod tests { }; use crate::commands::edge_app::EdgeAppCommand; - use httpmock::MockServer; - - use tempfile::tempdir; - pub fn create_edge_app_manifest_for_test(settings: Vec) -> EdgeAppManifest { EdgeAppManifest { syntax: MANIFEST_VERSION.to_owned(), diff --git a/src/commands/edge_app/utils.rs b/src/commands/edge_app/utils.rs index 851258c..5068daa 100644 --- a/src/commands/edge_app/utils.rs +++ b/src/commands/edge_app/utils.rs @@ -1,18 +1,17 @@ +use std::collections::{HashMap, HashSet}; +use std::env; +use std::path::{Path, PathBuf}; + +use log::debug; +use walkdir::{DirEntry, WalkDir}; + use crate::api::asset::AssetSignature; use crate::api::edge_app::setting::{Setting, SettingType}; use crate::commands::edge_app::instance_manifest::InstanceManifest; use crate::commands::edge_app::manifest::EdgeAppManifest; +use crate::commands::ignorer::Ignorer; use crate::commands::CommandError; use crate::signature::{generate_signature, sig_to_hex}; -use log::debug; -use std::collections::{HashMap, HashSet}; -use std::env; -use std::path::PathBuf; - -use crate::commands::ignorer::Ignorer; - -use std::path::Path; -use walkdir::{DirEntry, WalkDir}; const INSTANCE_FILE_NAME_ENV: &str = "INSTANCE_FILE_NAME"; const MANIFEST_FILE_NAME_ENV: &str = "MANIFEST_FILE_NAME"; @@ -311,15 +310,17 @@ pub fn validate_manifests_dependacies( #[cfg(test)] mod tests { + use std::fs::File; + use std::io::Write; + + use temp_env; + use tempfile::tempdir; + use super::*; use crate::api::edge_app::setting::{Setting, SettingType}; use crate::commands::edge_app::instance_manifest::INSTANCE_MANIFEST_VERSION; use crate::commands::edge_app::manifest::{Auth, Entrypoint, EntrypointType, MANIFEST_VERSION}; use crate::commands::edge_app::manifest_auth::AuthType; - use std::fs::File; - use std::io::Write; - use temp_env; - use tempfile::tempdir; fn create_manifest() -> EdgeAppManifest { EdgeAppManifest { diff --git a/src/commands/ignorer.rs b/src/commands/ignorer.rs index 8bbe698..4e3210c 100644 --- a/src/commands/ignorer.rs +++ b/src/commands/ignorer.rs @@ -1,6 +1,7 @@ +use std::path::{Path, PathBuf}; + use anyhow::Result; use regex::RegexSet; -use std::path::{Path, PathBuf}; pub struct Ignorer { base_path: PathBuf, @@ -47,12 +48,14 @@ impl Ignorer { #[cfg(test)] mod tests { - use super::Ignorer; use std::fs::File; use std::io::Write; use std::path::Path; + use tempfile::tempdir; + use super::Ignorer; + #[test] fn test_when_no_ignore_file_should_ignore_nothing() { let dir = tempdir().unwrap(); diff --git a/src/commands/mod.rs b/src/commands/mod.rs index d980ccb..93a6cc0 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,17 +1,15 @@ -use crate::api::edge_app::app::EdgeApps; -use crate::api::edge_app::installation::EdgeAppInstances; -use crate::{Authentication, AuthenticationError}; -use prettytable::{cell, Cell, Row}; - -use log::debug; use std::time::Duration; +use log::debug; +use prettytable::{cell, Cell, Row}; +use reqwest::header::{HeaderMap, InvalidHeaderValue}; +use reqwest::StatusCode; use serde::{Deserialize, Deserializer, Serialize}; - use thiserror::Error; -use reqwest::header::{HeaderMap, InvalidHeaderValue}; -use reqwest::StatusCode; +use crate::api::edge_app::app::EdgeApps; +use crate::api::edge_app::installation::EdgeAppInstances; +use crate::{Authentication, AuthenticationError}; pub mod asset; pub mod edge_app; diff --git a/src/commands/playlist.rs b/src/commands/playlist.rs index 450cb59..02e2f00 100644 --- a/src/commands/playlist.rs +++ b/src/commands/playlist.rs @@ -1,7 +1,8 @@ +use serde_json::json; + use crate::authentication::Authentication; use crate::commands; use crate::commands::{CommandError, PlaylistFile, PlaylistItem, PlaylistItems, Playlists}; -use serde_json::json; const POSITION_MULTIPLIER: u64 = 100000; pub struct PlaylistCommand { @@ -162,13 +163,14 @@ impl PlaylistCommand { #[cfg(test)] mod tests { - use super::*; - use crate::authentication::Config; + use std::ffi::OsString; use envtestkit::set_env; use httpmock::Method::{DELETE, GET, PATCH, POST}; use httpmock::MockServer; - use std::ffi::OsString; + + use super::*; + use crate::authentication::Config; #[test] fn test_create_playlist_should_send_correct_request() { diff --git a/src/commands/screen.rs b/src/commands/screen.rs index 9ca7344..15f32c2 100644 --- a/src/commands/screen.rs +++ b/src/commands/screen.rs @@ -1,10 +1,11 @@ +use std::collections::HashMap; + +use reqwest::StatusCode; + use crate::authentication::Authentication; use crate::commands; use crate::commands::{CommandError, Screens}; -use reqwest::StatusCode; -use std::collections::HashMap; - pub struct ScreenCommand { authentication: Authentication, } @@ -67,16 +68,14 @@ impl ScreenCommand { #[cfg(test)] mod tests { - use super::*; - - use httpmock::{Method::GET, MockServer}; - - use httpmock::Method::{DELETE, POST}; + use httpmock::Method::{DELETE, GET, POST}; + use httpmock::MockServer; + use serde_json::{json, Value}; + use tempfile::tempdir; + use super::*; use crate::authentication::{Authentication, Config}; use crate::commands::{Formatter, OutputType}; - use serde_json::{json, Value}; - use tempfile::tempdir; #[test] fn test_list_screens_should_return_correct_screen_list() { diff --git a/src/main.rs b/src/main.rs index c3064e8..ce4e956 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,11 +7,12 @@ mod signature; extern crate prettytable; -use crate::authentication::{Authentication, AuthenticationError}; +use std::env; + use clap::Parser; use simple_logger::{init_with_env, SimpleLogger}; -use std::env; +use crate::authentication::{Authentication, AuthenticationError}; fn main() { if env::var("RUST_LOG").is_ok() { diff --git a/src/signature.rs b/src/signature.rs index b177cf3..410c974 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -1,15 +1,14 @@ -use crate::commands::CommandError; - -use crate::pb_signature::signature::Hash; -use crate::pb_signature::Signature; -use protobuf::Message; -use sha2::Digest; -use sha2::Sha256; use std::fs::File; - use std::io::Read; use std::path::Path; +use protobuf::Message; +use sha2::{Digest, Sha256}; + +use crate::commands::CommandError; +use crate::pb_signature::signature::Hash; +use crate::pb_signature::Signature; + pub fn sig_to_hex(signature: &Signature) -> String { let serialized_bytes = signature .write_to_bytes() @@ -59,10 +58,12 @@ pub fn checksum(chunk: &[u8]) -> Vec { #[cfg(test)] mod tests { - use super::*; use std::fs; + use tempfile::tempdir; + use super::*; + #[test] fn test_generate_signature_when_file_does_not_exist_should_return_error() { let file_path = Path::new("/non-existent-file"); From dd46a5d0b93f581a7cebc10327fa9a8cc5965ccb Mon Sep 17 00:00:00 2001 From: Sergey Borovkov Date: Wed, 6 Aug 2025 21:33:28 +0400 Subject: [PATCH 3/3] Formatting --- build.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.rs b/build.rs index a9fc4bc..b205c3d 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,5 @@ -use std::env; -use std::fs; use std::path::Path; +use std::{env, fs}; const CONFIG: &str = "config.rs"; const LOCAL_API_URL: &str = "https://login.screenly.local";