use rust_util::util_os::get_user_home; use serde::Deserialize; use std::collections::BTreeMap; use std::fs; use std::path::PathBuf; use crate::util::{SCRIPT_DOT_EXT, SCRIPT_HYPHEN_EXT}; #[cfg(feature = "switch-rust-lang")] const FILE_META: &str = "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/script-meta.json"; #[cfg(feature = "switch-go-lang")] const FILE_META: &str = "https://git.hatter.ink/hatter/go-scripts/raw/branch/main/script-meta.json"; #[cfg(feature = "switch-js-lang")] const FILE_META: &str = "https://git.hatter.ink/hatter/js-scripts/raw/branch/main/script-meta.json"; #[cfg(feature = "switch-dart-lang")] const FILE_META: &str = "https://git.hatter.ink/hatter/dart-scripts/raw/branch/main/script-meta.json"; #[derive(Deserialize)] struct ScriptMeta { script_name: String, script_length: u64, script_sha256: String, } pub fn list_scripts(filter: Option<&String>) { debugging!("Loading URL: {}", FILE_META); let response = reqwest::blocking::get(FILE_META).unwrap_or_else(|e| { failure_and_exit!("Get file-meta.json failed: {}", e); }); debugging!("Load response: {}", response.status().as_u16()); if response.status().as_u16() != 200 { failure_and_exit!("Get file-meta.json failed, status: {}", response.status().as_u16()); } let text = response.text().unwrap_or_else(|e| { failure_and_exit!("Get file-meta.json failed: {}", e); }); debugging!("Response text: {}", &text); let user_home = get_user_home().expect("Get user home failed!"); let script_meta_map: BTreeMap = serde_json::from_str(&text).expect("Parse script-meta.json failed."); let mut messages = vec![]; for (_, script_meta) in &script_meta_map { let script_name = &script_meta.script_name; let real_script_name = if script_name.ends_with(SCRIPT_HYPHEN_EXT) { script_name.chars().take(script_name.len() - SCRIPT_HYPHEN_EXT.len()).collect::() + SCRIPT_DOT_EXT } else { script_name.to_string() }; if let Some(filter) = filter { if !real_script_name.contains(filter) { // NOT CONTAINS `filter`, SKIP continue; } } let full_script_path = PathBuf::from(&user_home).join("bin").join(&real_script_name); let is_script_exists = full_script_path.is_file(); let script_sha256 = if is_script_exists { let script_content = fs::read(&full_script_path).unwrap_or(vec![]); sha256::digest(&script_content) } else { "".to_string() }; let is_script_matches = script_sha256 == script_meta.script_sha256; let script_size = rust_util::util_size::get_display_size(script_meta.script_length as i64); let padding_length = 40 - real_script_name.len(); messages.push(format!("- {} {} {} {}", iff!(is_script_exists, iff!(is_script_matches, "✅", "✔️ "), "➖"), real_script_name, ".".repeat(iff!(padding_length < 1, 1, padding_length)), script_size, )); } if filter.is_some() { messages.insert(0, format!("Total {} script(s), found {} script(s):", script_meta_map.len(), messages.len())); } else { messages.insert(0, format!("Found {} script(s):", script_meta_map.len())); } success!("{}", messages.join("\n")); }