Skip to content

Commit

Permalink
feat: parse script data source reference (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
bc-m authored Sep 12, 2024
1 parent 83efacf commit aeebe07
Show file tree
Hide file tree
Showing 21 changed files with 278 additions and 91 deletions.
56 changes: 56 additions & 0 deletions src/script_steps/parameters/data_source_reference.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::utils::attributes::parse_unescaped_attribute;
use quick_xml::events::{BytesStart, Event};
use quick_xml::Reader;

#[derive(Debug, Default)]
pub struct DataSourceReference {
pub id: Option<String>,
pub name: Option<String>,
}

impl DataSourceReference {
pub fn from_xml(reader: &mut Reader<&[u8]>, _e: &BytesStart) -> Option<DataSourceReference> {
let mut depth = 1;
let mut item = DataSourceReference {
id: None,
name: None,
};

let mut buf: Vec<u8> = Vec::new();
loop {
match reader.read_event_into(&mut buf) {
Err(_) => continue,
Ok(Event::Eof) => break,
Ok(Event::Start(e)) => {
depth += 1;
if e.name().as_ref() == b"DataSourceReference" {
item.id = parse_unescaped_attribute(&e, "id");
item.name = parse_unescaped_attribute(&e, "name");
}
}
Ok(Event::End(_)) => {
depth -= 1;
if depth == 0 {
break;
}
}
_ => {}
}
buf.clear();
}

Some(item)
}

pub fn display(&self) -> Option<String> {
if let Some(name) = &self.name {
if self.id == Some(String::from("0")) {
Some(name.clone())
} else {
Some(format!("\"{}\"", name))
}
} else {
None
}
}
}
2 changes: 2 additions & 0 deletions src/script_steps/parameters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ pub(crate) mod boolean_container;
pub(crate) mod calculation;
pub(crate) mod comment;
pub(crate) mod constants;
pub(crate) mod data_source_reference;
pub(crate) mod field_reference;
pub(crate) mod layout_reference;
pub(crate) mod list;
pub(crate) mod parameter_values;
pub(crate) mod related;
pub(crate) mod script_reference;
pub(crate) mod select;
pub(crate) mod style;
pub(crate) mod target;
Expand Down
18 changes: 18 additions & 0 deletions src/script_steps/parameters/parameter_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ use crate::script_steps::parameters::animation::Animation;
use crate::script_steps::parameters::boolean::Boolean;
use crate::script_steps::parameters::calculation::Calculation;
use crate::script_steps::parameters::comment::Comment;
use crate::script_steps::parameters::data_source_reference::DataSourceReference;
use crate::script_steps::parameters::field_reference::FieldReference;
use crate::script_steps::parameters::layout_reference::LayoutReferenceContainer;
use crate::script_steps::parameters::list::List;
use crate::script_steps::parameters::related::Related;
use crate::script_steps::parameters::script_reference::ScriptReference;
use crate::script_steps::parameters::target::Target;
use crate::script_steps::parameters::window_reference::WindowReference;
use crate::utils::attributes::get_attribute;
Expand Down Expand Up @@ -149,6 +151,22 @@ impl ParameterValues {
}
depth -= 1;
}
"ScriptReference" => {
if let Some(param_value) = ScriptReference::from_xml(reader, &e) {
if let Some(display) = param_value.display() {
item.parameters.push(display);
}
}
depth -= 1;
}
"DataSourceReference" => {
if let Some(param_value) = DataSourceReference::from_xml(reader, &e) {
if let Some(display) = param_value.display() {
item.parameters.push(display);
}
}
depth -= 1;
}
_ => {
item.parameters.push(format!(
r#"⚠️ PARAMETER "{}" NOT PARSED ⚠️"#,
Expand Down
66 changes: 66 additions & 0 deletions src/script_steps/parameters/script_reference.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use crate::utils::attributes::parse_unescaped_attribute;
use quick_xml::events::{BytesStart, Event};
use quick_xml::Reader;

#[derive(Debug, Default)]
pub struct ScriptReference {
pub data_source_name: Option<String>,
pub script_name: Option<String>,
}

impl ScriptReference {
pub fn from_xml(reader: &mut Reader<&[u8]>, _e: &BytesStart) -> Option<ScriptReference> {
let mut depth = 1;
let mut item = ScriptReference {
data_source_name: None,
script_name: None,
};

let mut buf: Vec<u8> = Vec::new();
loop {
match reader.read_event_into(&mut buf) {
Err(_) => continue,
Ok(Event::Eof) => break,
Ok(Event::Start(e)) => {
depth += 1;
match e.name().as_ref() {
b"DataSourceReference" => {
item.data_source_name = parse_unescaped_attribute(&e, "name")
}
b"ScriptReference" => {
item.script_name = parse_unescaped_attribute(&e, "name")
}
_ => {}
}
}
Ok(Event::End(_)) => {
depth -= 1;
if depth == 0 {
break;
}
}
_ => {}
}
buf.clear();
}

Some(item)
}

pub fn display(&self) -> Option<String> {
let mut parameters = vec![];

if let Some(script_name) = &self.script_name {
parameters.push(format!("\"{}\"", script_name));
}
if let Some(data_source_name) = &self.data_source_name {
parameters.push(format!("from file \"{}\"", data_source_name));
}

if !parameters.is_empty() {
Some(parameters.join(" "))
} else {
None
}
}
}
67 changes: 54 additions & 13 deletions src/script_steps/perform_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use quick_xml::events::Event;
use quick_xml::Reader;

use crate::script_steps::parameters::calculation::Calculation;
use crate::utils::attributes::get_attribute;
use crate::utils::attributes::{get_attribute, parse_unescaped_attribute};

pub fn sanitize(step: &str) -> Option<String> {
let mut name = String::new();
let mut data_source_reference: Option<String> = None;
let mut script_reference_type = String::new();
let mut script_reference_type_id = String::new();
let mut script_reference = String::new();
Expand All @@ -31,9 +32,10 @@ pub fn sanitize(step: &str) -> Option<String> {
.unwrap();
}
}
b"ScriptReference" => {
script_reference = get_attribute(&e, "name").unwrap().to_string();
b"DataSourceReference" => {
data_source_reference = parse_unescaped_attribute(&e, "name")
}
b"ScriptReference" => script_reference = parse_unescaped_attribute(&e, "name")?,
b"Parameter" => {
if get_attribute(&e, "type").unwrap_or("".to_string()).as_str() == "Parameter" {
calculation = Calculation::from_xml(&mut reader, &e)
Expand All @@ -49,23 +51,27 @@ pub fn sanitize(step: &str) -> Option<String> {
buf.clear()
}

let mut parameters = vec![script_reference_type.to_string()];

if script_reference_type_id.as_str() != "2" {
script_reference = format!("\"{}\"", script_reference);
parameters.push(format!("\"{}\"", script_reference));
} else {
parameters.push(script_reference.to_string());
}

if let Some(ref data_source_value) = data_source_reference {
parameters.push(format!("File: \"{}\"", data_source_value));
}

if !calculation.is_empty() {
parameters.push(format!("Parameter: {}", calculation));
}

if name.is_empty() {
println!("empty primitive");
None
} else if calculation.is_empty() {
Some(format!(
"{} [ {} ; {} ]",
name, script_reference_type, script_reference
))
} else {
Some(format!(
"{} [ {} ; {} ; Parameter: {} ]",
name, script_reference_type, script_reference, calculation
))
Some(format!("{} [ {} ]", name, parameters.join(" ; ")))
}
}

Expand Down Expand Up @@ -170,4 +176,39 @@ mod tests {
Some(r#"Script ausführen [ Nach Name ; "Do something" ; Parameter: 123 ]"#.to_string());
assert_eq!(sanitize(xml.trim()), expected_output);
}

#[test]
fn test_run_external_script() {
let xml = r#"
<Step id="1" name="Script ausführen" enable="True">
<Options>80</Options>
<ParameterValues membercount="2">
<Parameter type="List">
<List name="Aus Liste" value="1">
<DataSourceReference id="1" name="App_Utils"></DataSourceReference>
<ScriptReference id="724" name="Do something"></ScriptReference>
</List>
</Parameter>
<Parameter type="Parameter">
<Parameter>
<Calculation datatype="1" position="0">
<Calculation>
<Text><![CDATA[123]]></Text>
<ChunkList hash="90213DC459B04C5A47C044B9460AEF7B">
<Chunk type="NoRef">123</Chunk>
</ChunkList>
</Calculation>
</Calculation>
</Parameter>
</Parameter>
</ParameterValues>
</Step>
"#;

let expected_output = Some(
r#"Script ausführen [ Aus Liste ; "Do something" ; File: "App_Utils" ; Parameter: 123 ]"#
.to_string(),
);
assert_eq!(sanitize(xml.trim()), expected_output);
}
}
4 changes: 4 additions & 0 deletions src/utils/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use std::borrow::Cow;
use quick_xml::events::BytesStart;
use quick_xml::name::QName;

pub fn parse_unescaped_attribute(e: &BytesStart, attribute: &str) -> Option<String> {
get_attribute(e, attribute).map(|text| quick_xml::escape::unescape(&text).unwrap().to_string())
}

pub fn key_to_string(key: QName) -> String {
return String::from_utf8_lossy(key.as_ref()).to_string();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Wenn [ NICHT _Palette::__ID ]
Ende (wenn)
# FIXME: This broke after restructuring
Script ausführen [ Aus Liste ; "" ]
Script ausführen [ Aus Liste ; "" ; File: "<Unbekannt>" ]
# # Duplicate Palette
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Wenn [ 1=0 ]
Sonst, wenn [ 1=1 ]
Sonst
Ende (wenn)
BeiTimer-Script installieren [ ⚠️ PARAMETER "ScriptReference" NOT PARSED ⚠️ ]
BeiTimer-Script installieren [ "All script steps" ]
Schleife (Anfang) [ Flush: Immer ]
Verlasse Schleife wenn [ 1=1 ]
Schleife (Ende)
Expand Down Expand Up @@ -129,10 +129,10 @@ Datensätze zeigen als [ Durchwechseln ]
Zulässige Ausrichtungen festlegen

# Files
Datei schließen [ ⚠️ PARAMETER "DataSourceReference" NOT PARSED ⚠️ ]
Datei schließen [ Aktuelle Datei ]
Datei konvertieren [ SSL-Zertifikate verifizieren: OFF ; Datei öffnen: ON ; Indizes überspringen: OFF ; Mit Dialog: ON ]
Neue Datei
Datei öffnen [ Ausgeblendet öffnen: OFF ; ⚠️ PARAMETER "DataSourceReference" NOT PARSED ⚠️ ]
Datei öffnen [ Ausgeblendet öffnen: OFF ; <Unbekannt> ]
Drucken [ Mit Dialog: ON ; ⚠️ PARAMETER "Restore" NOT PARSED ⚠️ ; ⚠️ PARAMETER "Print" NOT PARSED ⚠️ ; ⚠️ PARAMETER "PageSetup" NOT PARSED ⚠️ ]
Drucker einrichten [ ⚠️ PARAMETER "Restore" NOT PARSED ⚠️ ; Mit Dialog: ON ; ⚠️ PARAMETER "PageSetup" NOT PARSED ⚠️ ]
Datei wiederherstellen [ Mit Dialog: ON ]
Expand Down
Loading

0 comments on commit aeebe07

Please sign in to comment.