use std::sync::Arc; use serde::{Deserialize, Serialize}; mod builder; mod parameter; pub use builder::Builder; pub use parameter::Parameter; #[derive(Serialize, Deserialize, Clone, Default, Debug)] pub struct Script { name: Arc, path: Arc, parameters: Vec, default_parameter_set: Option>, help_uri: Option>, supports_paging: Option>, supports_should_process: Option, positional_binding: Option, } #[allow(dead_code)] impl Script { pub fn builder() -> Builder { Builder::new() } pub fn name(&self) -> &str { &self.name } pub fn path(&self) -> &str { &self.path } pub fn parameters(&self) -> &Vec { &self.parameters } pub fn default_parameter_set(&self) -> Option<&str> { self.default_parameter_set.as_ref().map(|x| x as _) } pub fn help_uri(&self) -> Option<&str> { self.help_uri.as_ref().map(|x| x as _) } pub fn supports_paging(&self) -> Option<&str> { self.supports_paging.as_ref().map(|x| x as _) } pub fn supports_should_process(&self) -> Option { self.supports_should_process } pub fn positional_binding(&self) -> Option { self.positional_binding } pub fn from_file>(path: P) -> Result { let func = get_parse_function(); let ps_runner = format!( "{func}; parse_ps -Path '{}' | ConvertTo-Json -Depth 10", path.as_ref() ); let output = Command::new("pwsh") .args(["-NoProfile", "-Command", &ps_runner]) .output() .map_err(|e| e.to_string())?; if output.status.success() { let stdout_str = String::from_utf8_lossy(&output.stdout); Ok(serde_json::from_str(&stdout_str).map_err(|e| e.to_string())?) } else { Err(String::from("Failed to run PowerShell")) } } } use std::process::Command; #[allow(dead_code)] const PARSE_FUNCTION_RAW: &str = include_str!("../powershell/get-metadata.ps1"); #[allow(dead_code)] fn get_parse_function() -> String { format!("function parse_ps() {{{PARSE_FUNCTION_RAW}}}") } #[allow(dead_code)] fn parse_powershell_file(path: &str) -> Result { let func = get_parse_function(); let ps_runner = format!("{func}; parse_ps -Path '{path}' | ConvertTo-Json -Depth 10"); let output = Command::new("pwsh") .args(["-NoProfile", "-Command", &ps_runner]) .output() .map_err(|e| e.to_string())?; if output.status.success() { let stdout_str = String::from_utf8_lossy(&output.stdout); Ok(serde_json::from_str(&stdout_str).map_err(|e| e.to_string())?) } else { Err(String::from("Failed to run PowerShell")) } } #[cfg(test)] mod tests { #![allow(clippy::unwrap_used, clippy::expect_used)] use super::*; #[test] fn test_script_from_file() { let got = Script::from_file("powershell/test-script.ps1"); dbg!(&got); assert!(got.is_ok()); let got = got.unwrap(); assert_eq!("test-script.ps1", got.name()); } #[test] fn test_parse_powershell_file() { let got = parse_powershell_file("powershell/test-script.ps1"); assert!(got.is_ok()); } }