Compare commits

...

5 Commits

Author SHA1 Message Date
26533956ae feat: move parsing logic to script struct 2025-04-26 22:43:14 +02:00
d7a87e8609 feat: add serde + clone + debug + more datatypes 2025-04-26 22:42:18 +02:00
e613464413 chore: add clone + debug 2025-04-26 22:41:19 +02:00
1295e6209a chore: flatten cmdletBinding 2025-04-26 22:40:06 +02:00
63984526a7 chore: remove nullable
todo: maybe add this in the future
2025-04-26 22:39:23 +02:00
6 changed files with 117 additions and 48 deletions

View File

@ -153,9 +153,9 @@ $result = [pscustomobject]@{
name = $script_name
path = $script_path
parameters = $parameters
cmdletBinding = [pscustomobject]@{
defaultParameterSetName = $defaultParamSet ?? "Default"
}
#cmdletBinding = [pscustomobject]@{
defaultParameterSetName = $defaultParamSet ?? "Default"
#}
}
return $result

View File

@ -43,7 +43,7 @@
# Nullable type
[Parameter(ParameterSetName = 'Set1')]
[Nullable[bool]]$IsEnabled
[bool]$IsEnabled
)
process {}

View File

@ -1,40 +1 @@
mod script;
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<serde_json::Value, String> {
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 test {
use super::*;
#[test]
fn test_parse_powershell_file() {
let got = parse_powershell_file("powershell/test-script.ps1");
assert!(got.is_ok());
}
}

View File

@ -1 +1,100 @@
use std::sync::Arc;
use parameter::Parameter;
use serde::{Deserialize, Serialize};
mod parameter;
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
pub struct Script {
name: Arc<str>,
path: Arc<str>,
parameters: Vec<Parameter>,
default_parameter_set: Option<Arc<str>>,
help_uri: Option<Arc<str>>,
supports_paging: Option<Arc<str>>,
supports_should_process: Option<bool>,
positional_binding: Option<bool>,
}
#[allow(dead_code)]
impl Script {
pub fn name(&self) -> &str {
&self.name
}
pub fn path(&self) -> &str {
&self.path
}
pub fn from_file<P: AsRef<str>>(path: P) -> Result<Self, String> {
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<serde_json::Value, String> {
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 test {
#![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());
}
}

View File

@ -5,10 +5,13 @@ use validation::Validation;
mod validation;
#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Parameter {
name: Arc<str>,
#[serde(rename = "type")]
data_type: DataType,
#[serde(skip)]
is_array: bool,
aliases: Vec<Arc<str>>,
description: Option<Arc<str>>,
@ -17,7 +20,7 @@ pub struct Parameter {
validations: Vec<Validation>,
}
#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, Clone, PartialEq, Eq, Default, Debug)]
pub struct ParameterSet {
name: Arc<str>,
mandatory: bool,
@ -26,13 +29,19 @@ pub struct ParameterSet {
value_from_pipeline_by_property_name: Option<bool>,
}
#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, Clone, Debug)]
pub enum DataType {
DateTime,
//TODO: Make this Variant obsolete by implementing De-/Serialize on the using Structs
#[serde(rename = "String[]")]
StringArray,
String,
Int32,
Int64,
#[serde(rename = "SwitchParameter")]
Switch,
Bool,
Boolean,
#[serde(rename = "PSCredential")]
Credential,
SecureString,
}

View File

@ -2,7 +2,7 @@ use std::sync::Arc;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, Clone, Debug)]
#[serde(tag = "type")]
pub enum Validation {
#[serde(rename = "ValidateNotNullOrEmpty")]