Skip to content

Commit

Permalink
refactor(cfc): Serializer API (PLC-lang#967)
Browse files Browse the repository at this point in the history
Introduces a new API for the serializer making it more concise
  • Loading branch information
volsa authored Nov 3, 2023
1 parent 48cccc9 commit c9e0ed8
Show file tree
Hide file tree
Showing 22 changed files with 785 additions and 1,914 deletions.
195 changes: 88 additions & 107 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion compiler/plc_xml/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ pub(crate) mod model {
pub mod variables;
}
mod reader;
mod serializer;
pub(crate) mod serializer;
20 changes: 8 additions & 12 deletions compiler/plc_xml/src/model/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl<'xml> Parseable for Block<'xml> {
let Some(tag) = tag else { unreachable!() };
let attributes = get_attributes(tag.attributes())?;
let mut variables = Vec::new();

loop {
match reader.read_event().map_err(Error::ReadEvent)? {
Event::Start(tag) => match tag.name().as_ref() {
Expand Down Expand Up @@ -67,23 +68,18 @@ mod tests {
use crate::{
model::block::Block,
reader::{get_start_tag, Reader},
serializer::{XBlock, XInOutVariables, XInputVariables, XOutputVariables, XVariable},
serializer::{SBlock, SVariable},
xml_parser::Parseable,
};

#[test]
fn add_block() {
let content = XBlock::init("1", "ADD", "0")
.with_input_variables(
XInputVariables::new()
.with_variable(XVariable::init("a", false).with_connection_in_initialized("1"))
.with_variable(XVariable::init("b", false).with_connection_in_initialized("2")),
)
.with_inout_variables(XInOutVariables::new().close())
.with_output_variables(
XOutputVariables::new()
.with_variable(XVariable::init("c", false).with_connection_out_initialized()),
)
let content = SBlock::init("ADD", 1, 0)
.with_input(vec![
&SVariable::new().with_name("a").connect(1),
&SVariable::new().with_name("b").connect(2),
])
.with_output(vec![&SVariable::new().with_name("c")])
.serialize();

let mut reader = Reader::new(&content);
Expand Down
32 changes: 10 additions & 22 deletions compiler/plc_xml/src/model/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,40 +43,28 @@ mod tests {
use crate::{
model::body::Body,
reader::{get_start_tag, Reader},
serializer::{XBlock, XBody, XFbd, XInOutVariables, XInputVariables, XOutputVariables, XVariable},
serializer::{SBlock, SBody, SVariable},
xml_parser::Parseable,
};

#[test]
fn empty() {
let content = XBody::new().with_fbd(XFbd::new().close()).serialize();
let content = SBody::new().with_fbd(vec![]).serialize();

let mut reader = Reader::new(&content);
assert_debug_snapshot!(Body::visit(&mut reader, None).unwrap());
}

#[test]
fn fbd_with_add_block() {
let content = XBody::new()
.with_fbd(
XFbd::new().with_block(
XBlock::init("1", "ADD", "0")
.with_input_variables(
XInputVariables::new()
.with_variable(
XVariable::init("a", false).with_connection_in_initialized("1"),
)
.with_variable(
XVariable::init("b", false).with_connection_in_initialized("2"),
),
)
.with_inout_variables(XInOutVariables::new().close())
.with_output_variables(
XOutputVariables::new()
.with_variable(XVariable::init("c", false).with_connection_out_initialized()),
),
),
)
let content = SBody::new()
.with_fbd(vec![&SBlock::init("ADD", 1, 0)
.with_input(vec![
&SVariable::new().with_name("a").connect(1),
&SVariable::new().with_name("b").connect(2),
])
.with_output(vec![&SVariable::new().with_name("c")])
.with_inout(vec![])])
.serialize();

let mut reader = Reader::new(&content);
Expand Down
59 changes: 14 additions & 45 deletions compiler/plc_xml/src/model/fbd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ impl<'xml> Node<'xml> {
impl<'xml> Parseable for FunctionBlockDiagram<'xml> {
fn visit(reader: &mut Reader, _tag: Option<BytesStart>) -> Result<Self, Error> {
let mut nodes = IndexMap::new();

loop {
match reader.read_event().map_err(Error::ReadEvent)? {
Event::Start(tag) => match tag.name().as_ref() {
Expand Down Expand Up @@ -292,16 +293,13 @@ impl<'xml> ConnectionResolver<'xml> for NodeIndex<'xml> {

#[cfg(test)]
mod tests {
use crate::serializer::{SBlock, SInVariable, SOutVariable, SVariable, YFbd};
use crate::{
model::{
connector::Connector, fbd::FunctionBlockDiagram, pou::Pou, project::Project,
variables::FunctionBlockVariable,
},
reader::{get_start_tag, Reader},
serializer::{
XBlock, XConnection, XConnectionPointIn, XConnectionPointOut, XExpression, XFbd, XInOutVariables,
XInVariable, XInputVariables, XOutVariable, XOutputVariables, XPosition, XRelPosition, XVariable,
},
xml_parser::Parseable,
};
use insta::assert_debug_snapshot;
Expand All @@ -311,47 +309,18 @@ mod tests {

#[test]
fn add_block() {
let content = XFbd::new()
.with_block(
XBlock::init("1", "ADD", "0")
.with_input_variables(
XInputVariables::new()
.with_variable(XVariable::init("a", false).with_connection_in_initialized("1"))
.with_variable(XVariable::init("b", false).with_connection_in_initialized("2")),
)
.with_inout_variables(XInOutVariables::new().close())
.with_output_variables(
XOutputVariables::new()
.with_variable(XVariable::init("c", false).with_connection_out_initialized()),
),
)
.with_in_variable(
XInVariable::init("2", false)
.with_position(XPosition::new().close())
.with_connection_point_out(
XConnectionPointOut::new().with_rel_position(XRelPosition::init()),
)
.with_expression(XExpression::new().with_data("a")),
)
.with_in_variable(
XInVariable::init("3", false)
.with_position(XPosition::new().close())
.with_connection_point_out(
XConnectionPointOut::new().with_rel_position(XRelPosition::init()),
)
.with_expression(XExpression::new().with_data("b")),
)
.with_out_variable(
XOutVariable::init("4", false)
.with_position(XPosition::new().close())
.with_attribute("executionOrderId", "1")
.with_connection_point_in(
XConnectionPointIn::new()
.with_rel_position(XRelPosition::init())
.with_connection(XConnection::new().with_attribute("refLocalId", "1")),
)
.with_expression(XExpression::new().with_data("c")),
)
let content = YFbd::new()
.children(vec![
&SBlock::init("ADD", 1, 0)
.with_input(vec![
&SVariable::new().with_name("a").connect(1),
&SVariable::new().with_name("b").connect(2),
])
.with_output(vec![&SVariable::new().with_name("c")]),
&SInVariable::new().with_id(2).with_expression("a"),
&SInVariable::new().with_id(3).with_expression("b"),
&SOutVariable::new().with_id(4).with_expression("c").with_execution_id(1).connect(1),
])
.serialize();

let mut reader = Reader::new(&content);
Expand Down
43 changes: 7 additions & 36 deletions compiler/plc_xml/src/model/pou.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,50 +121,24 @@ impl FromStr for PouType {
mod tests {
use insta::assert_debug_snapshot;

use crate::serializer::SPou;
use crate::{
model::pou::Pou,
reader::{get_start_tag, Reader},
serializer::{
XAddData, XBody, XContent, XData, XFbd, XInterface, XLocalVars, XPou, XTextDeclaration,
},
xml_parser::{self, Parseable},
};

#[test]
fn empty() {
let content = XPou::new()
.with_attribute("xmlns", "http://www.plcopen.org/xml/tc6_0201")
.with_attribute("name", "foo")
.with_attribute("pouType", "program")
.with_interface(
XInterface::new().with_local_vars(XLocalVars::new().close()).with_add_data(
XAddData::new().with_data_data(
XData::new()
.with_attribute("name", "www.bachmann.at/plc/plcopenxml")
.with_attribute("handleUnknown", "implementation")
.with_text_declaration(XTextDeclaration::new().with_content(
XContent::new().with_data(
r#"
PROGRAM foo
VAR
END_VAR
"#,
),
)),
),
),
)
.with_body(XBody::new().with_fbd(XFbd::new().close()))
.serialize();
let declaration = "PROGRAM foo VAR END_VAR";
let content = SPou::init("foo", "program", declaration).with_fbd(vec![]).serialize();

assert_debug_snapshot!(xml_parser::visit(&content));
}

#[test]
fn poutype_program() {
let content =
XPou::new().with_attribute("name", "foo").with_attribute("pouType", "program").serialize();
let content = SPou::init("foo", "program", "").serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand All @@ -173,8 +147,7 @@ END_VAR

#[test]
fn poutype_function() {
let content =
XPou::new().with_attribute("name", "foo").with_attribute("pouType", "function").serialize();
let content = SPou::init("foo", "function", "").serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand All @@ -183,8 +156,7 @@ END_VAR

#[test]
fn poutype_function_block() {
let content =
XPou::new().with_attribute("name", "foo").with_attribute("pouType", "functionBlock").serialize();
let content = SPou::init("foo", "functionBlock", "").serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand All @@ -193,8 +165,7 @@ END_VAR

#[test]
fn poutype_unknown() {
let content =
XPou::new().with_attribute("name", "foo").with_attribute("pouType", "asdasd").serialize();
let content = SPou::init("foo", "asdasd", "").serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Ok(
Interface {
add_data: Some(
Data {
content: "PROGRAM foo\nVAR\n\nEND_VAR\nEND_PROGRAM",
content: "PROGRAM foo VAR END_VAR\nEND_PROGRAM",
handle: Implementation,
},
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Ok(
},
},
actions: [],
interface: None,
interface: Some(
Interface {
add_data: None,
},
),
},
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Ok(
},
},
actions: [],
interface: None,
interface: Some(
Interface {
add_data: None,
},
),
},
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Ok(
},
},
actions: [],
interface: None,
interface: Some(
Interface {
add_data: None,
},
),
},
)
19 changes: 8 additions & 11 deletions compiler/plc_xml/src/model/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,19 +223,18 @@ impl Parseable for BlockVariable {
mod tests {
use insta::assert_debug_snapshot;

use crate::serializer::{
SInOutVariables, SInVariable, SInputVariables, SOutVariable, SOutputVariables, SVariable,
};
use crate::{
model::variables::{BlockVariable, FunctionBlockVariable},
reader::{get_start_tag, Reader},
serializer::{
XExpression, XInOutVariables, XInVariable, XInputVariables, XOutVariable, XOutputVariables,
XVariable,
},
xml_parser::Parseable,
};

#[test]
fn block_input_variable() {
let content = XInputVariables::new().with_variable(XVariable::init("", false)).serialize();
let content = SInputVariables::new().children(vec![&SVariable::new().with_name("")]).serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand All @@ -245,7 +244,7 @@ mod tests {

#[test]
fn block_output_variable() {
let content = XOutputVariables::new().with_variable(XVariable::init("", false)).serialize();
let content = SOutputVariables::new().children(vec![&SVariable::new().with_name("")]).serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand All @@ -255,7 +254,7 @@ mod tests {

#[test]
fn block_inout_variable() {
let content = XInOutVariables::new().with_variable(XVariable::init("", false)).serialize();
let content = SInOutVariables::new().children(vec![&SVariable::new().with_name("")]).serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand All @@ -265,8 +264,7 @@ mod tests {

#[test]
fn fbd_in_variable() {
let content =
XInVariable::init("0", false).with_expression(XExpression::new().with_data("a")).serialize();
let content = SInVariable::id(0).with_expression("a").serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand All @@ -275,8 +273,7 @@ mod tests {

#[test]
fn fbd_out_variable() {
let content =
XOutVariable::init("0", false).with_expression(XExpression::new().with_data("a")).serialize();
let content = SOutVariable::id(0).with_expression("a").serialize();

let mut reader = Reader::new(&content);
let tag = get_start_tag(reader.read_event().unwrap());
Expand Down
Loading

0 comments on commit c9e0ed8

Please sign in to comment.