Skip to content

Commit 4361c3f

Browse files
committed
Add SequenceSerializer
1 parent 94e4b70 commit 4361c3f

12 files changed

Lines changed: 331 additions & 15 deletions

File tree

plantuml/parser/integration_test/sequence_diagram/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
filegroup(
1414
name = "simple_sequence_test",
1515
srcs = [
16-
"simple_sequence.puml",
1716
"simple_sequence.json",
17+
"simple_sequence.puml",
1818
],
1919
visibility = ["//visibility:public"],
2020
)

plantuml/parser/integration_test/sequence_diagram/simple_sequence.puml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
' *******************************************************************************
2+
' Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
'
4+
' See the NOTICE file(s) distributed with this work for additional
5+
' information regarding copyright ownership.
6+
'
7+
' This program and the accompanying materials are made available under the
8+
' terms of the Apache License Version 2.0 which is available at
9+
' https://www.apache.org/licenses/LICENSE-2.0
10+
'
11+
' SPDX-License-Identifier: Apache-2.0
12+
' *******************************************************************************
13+
114
@startuml
215

316
participant "Component A" as ComponentA <<component>>

plantuml/parser/puml_resolver/src/sequence_diagram/src/logic_parser.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
///////////////////////////////////////////////////////////////////////////////////
1+
// *******************************************************************************
22
// Copyright (c) 2026 Contributors to the Eclipse Foundation
33
//
44
// See the NOTICE file(s) distributed with this work for additional
55
// information regarding copyright ownership.
66
//
77
// This program and the accompanying materials are made available under the
88
// terms of the Apache License Version 2.0 which is available at
9-
// https://www.apache.org/licenses/LICENSE-2.0
9+
// <https://www.apache.org/licenses/LICENSE-2.0>
1010
//
1111
// SPDX-License-Identifier: Apache-2.0
12-
////////////////////////////////////////////////////////////////////////////////////
12+
// *******************************************************************************
1313
//! Logic parser module for constructing and visualizing sequence node trees
1414
1515
use sequence_logic::*;

plantuml/parser/puml_resolver/src/sequence_diagram/test/logic_parse_test.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
///////////////////////////////////////////////////////////////////////////////////
1+
// *******************************************************************************
22
// Copyright (c) 2026 Contributors to the Eclipse Foundation
33
//
44
// See the NOTICE file(s) distributed with this work for additional
55
// information regarding copyright ownership.
66
//
77
// This program and the accompanying materials are made available under the
88
// terms of the Apache License Version 2.0 which is available at
9-
// https://www.apache.org/licenses/LICENSE-2.0
9+
// <https://www.apache.org/licenses/LICENSE-2.0>
1010
//
1111
// SPDX-License-Identifier: Apache-2.0
12-
////////////////////////////////////////////////////////////////////////////////////
13-
12+
// *******************************************************************************
1413
//! Logic parser test suite: Compare logic_parse output with expected JSON
1514
1615
use sequence_parser::syntax_ast::Statement;
@@ -21,8 +20,7 @@ use std::fs;
2120
#[test]
2221
fn test_logic_parse_output() {
2322
// Read the syntax.json file
24-
let syntax_file =
25-
"plantuml/parser/integration_test/sequence_diagram/simple_sequence.json";
23+
let syntax_file = "plantuml/parser/integration_test/sequence_diagram/simple_sequence.json";
2624
let expected_file = "plantuml/parser/puml_resolver/src/sequence_diagram/test/logic.json";
2725

2826
let json_content = fs::read_to_string(syntax_file)
@@ -65,8 +63,7 @@ fn test_logic_parse_output() {
6563

6664
#[test]
6765
fn test_logic_parse_nested_loops_match_branch_nesting_rules() {
68-
let syntax_file =
69-
"plantuml/parser/integration_test/sequence_diagram/simple_sequence.json";
66+
let syntax_file = "plantuml/parser/integration_test/sequence_diagram/simple_sequence.json";
7067

7168
let json_content = fs::read_to_string(syntax_file)
7269
.unwrap_or_else(|e| panic!("Error reading input file '{}': {}", syntax_file, e));

plantuml/parser/puml_serializer/BUILD

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ rust_library(
1919
deps = [
2020
":class_serializer",
2121
":component_serializer",
22+
":sequence_serializer",
2223
],
2324
)
2425

@@ -33,3 +34,9 @@ alias(
3334
actual = "//plantuml/parser/puml_serializer/src/serialize:puml_serialize_class",
3435
visibility = ["//plantuml/parser:__subpackages__"],
3536
)
37+
38+
alias(
39+
name = "sequence_serializer",
40+
actual = "//plantuml/parser/puml_serializer/src/serialize:puml_serialize_sequence",
41+
visibility = ["//plantuml/parser:__subpackages__"],
42+
)

plantuml/parser/puml_serializer/src/fbs/BUILD

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,35 @@ rust_library(
7777
"@crates//:flatbuffers",
7878
],
7979
)
80+
81+
flatbuffer_library_public(
82+
name = "sequence_fbs_codegen",
83+
srcs = [
84+
"//tools/metamodel:sequence_schemas",
85+
],
86+
outs = [
87+
"sequence_diagram_generated.rs",
88+
],
89+
flatc_args = [],
90+
language_flag = "--rust",
91+
visibility = ["//plantuml/parser:__subpackages__"],
92+
)
93+
94+
rust_library(
95+
name = "sequence_fbs",
96+
srcs = [
97+
":sequence_fbs_codegen",
98+
],
99+
rustc_flags = [
100+
"--allow=unused_imports",
101+
"--allow=clippy::extra-unused-lifetimes",
102+
"--allow=clippy::missing-safety-doc",
103+
"--allow=clippy::needless-lifetimes",
104+
],
105+
visibility = [
106+
"//plantuml/parser:__subpackages__",
107+
],
108+
deps = [
109+
"@crates//:flatbuffers",
110+
],
111+
)

plantuml/parser/puml_serializer/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313

1414
pub use class_serializer::ClassSerializer;
1515
pub use component_serializer::ComponentSerializer;
16+
pub use sequence_serializer::SequenceSerializer;

plantuml/parser/puml_serializer/src/serialize/BUILD

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,18 @@ rust_library(
4141
"@crates//:flatbuffers",
4242
],
4343
)
44+
45+
rust_library(
46+
name = "puml_serialize_sequence",
47+
srcs = [
48+
"sequence_serializer.rs",
49+
],
50+
crate_name = "sequence_serializer",
51+
crate_root = "sequence_serializer.rs",
52+
visibility = ["//plantuml/parser:__subpackages__"],
53+
deps = [
54+
"//plantuml/parser/puml_serializer/src/fbs:sequence_fbs",
55+
"//tools/metamodel:sequence_diagram",
56+
"@crates//:flatbuffers",
57+
],
58+
)
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// *******************************************************************************
2+
// Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
//
4+
// See the NOTICE file(s) distributed with this work for additional
5+
// information regarding copyright ownership.
6+
//
7+
// This program and the accompanying materials are made available under the
8+
// terms of the Apache License Version 2.0 which is available at
9+
// <https://www.apache.org/licenses/LICENSE-2.0>
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
// *******************************************************************************
13+
14+
use flatbuffers::FlatBufferBuilder;
15+
use sequence_fbs::sequence_metamodel as fb;
16+
use sequence_logic::{ConditionType, Event, SequenceNode};
17+
18+
pub struct SequenceSerializer;
19+
20+
impl SequenceSerializer {
21+
pub fn serialize(
22+
nodes: &[SequenceNode],
23+
name: Option<&str>,
24+
source_files: &[String],
25+
version: Option<&str>,
26+
) -> Vec<u8> {
27+
let mut builder = FlatBufferBuilder::new();
28+
29+
let name_offset = name.map(|n| builder.create_string(n));
30+
31+
let node_offsets: Vec<_> = nodes
32+
.iter()
33+
.map(|node| Self::serialize_node(&mut builder, node))
34+
.collect();
35+
let nodes_offset = builder.create_vector(&node_offsets);
36+
37+
let source_offsets: Vec<_> = source_files
38+
.iter()
39+
.map(|s| builder.create_string(s))
40+
.collect();
41+
let source_files_offset = builder.create_vector(&source_offsets);
42+
43+
let version_offset = version.map(|v| builder.create_string(v));
44+
45+
let root = fb::SequenceDiagram::create(
46+
&mut builder,
47+
&fb::SequenceDiagramArgs {
48+
name: name_offset,
49+
root_interactions: Some(nodes_offset),
50+
source_files: Some(source_files_offset),
51+
version: version_offset,
52+
},
53+
);
54+
55+
builder.finish(root, Some("SEQD"));
56+
builder.finished_data().to_vec()
57+
}
58+
59+
fn serialize_node<'a>(
60+
builder: &mut FlatBufferBuilder<'a>,
61+
node: &SequenceNode,
62+
) -> flatbuffers::WIPOffset<fb::SequenceNode<'a>> {
63+
// Recursively serialize child nodes first (depth-first).
64+
let branch_offsets: Vec<_> = node
65+
.branches_node
66+
.iter()
67+
.map(|child| Self::serialize_node(builder, child))
68+
.collect();
69+
let branches_offset = builder.create_vector(&branch_offsets);
70+
71+
// Serialize the event union.
72+
let (event_type, event_offset) = Self::serialize_event(builder, &node.event);
73+
74+
fb::SequenceNode::create(
75+
builder,
76+
&fb::SequenceNodeArgs {
77+
event_type,
78+
event: Some(event_offset),
79+
branches_node: Some(branches_offset),
80+
},
81+
)
82+
}
83+
84+
fn serialize_event<'a>(
85+
builder: &mut FlatBufferBuilder<'a>,
86+
event: &Event,
87+
) -> (
88+
fb::Event,
89+
flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>,
90+
) {
91+
match event {
92+
Event::Interaction(interaction) => {
93+
let caller = builder.create_string(&interaction.caller);
94+
let callee = builder.create_string(&interaction.callee);
95+
let method = builder.create_string(&interaction.method);
96+
let offset = fb::Interaction::create(
97+
builder,
98+
&fb::InteractionArgs {
99+
caller: Some(caller),
100+
callee: Some(callee),
101+
method: Some(method),
102+
},
103+
);
104+
(fb::Event::Interaction, offset.as_union_value())
105+
}
106+
Event::Return(ret) => {
107+
let caller = builder.create_string(&ret.caller);
108+
let callee = builder.create_string(&ret.callee);
109+
let return_content = builder.create_string(&ret.return_content);
110+
let offset = fb::Return::create(
111+
builder,
112+
&fb::ReturnArgs {
113+
caller: Some(caller),
114+
callee: Some(callee),
115+
return_content: Some(return_content),
116+
},
117+
);
118+
(fb::Event::Return, offset.as_union_value())
119+
}
120+
Event::Condition(cond) => {
121+
let condition_value = builder.create_string(&cond.condition_value);
122+
let offset = fb::Condition::create(
123+
builder,
124+
&fb::ConditionArgs {
125+
condition_type: Self::map_condition_type(cond.condition_type.clone()),
126+
condition_value: Some(condition_value),
127+
},
128+
);
129+
(fb::Event::Condition, offset.as_union_value())
130+
}
131+
}
132+
}
133+
134+
fn map_condition_type(ct: ConditionType) -> fb::ConditionType {
135+
match ct {
136+
ConditionType::Opt => fb::ConditionType::Opt,
137+
ConditionType::Alt => fb::ConditionType::Alt,
138+
ConditionType::Loop => fb::ConditionType::Loop,
139+
ConditionType::Par => fb::ConditionType::Par,
140+
ConditionType::Par2 => fb::ConditionType::Par2,
141+
ConditionType::Break => fb::ConditionType::Break,
142+
ConditionType::Critical => fb::ConditionType::Critical,
143+
ConditionType::Else => fb::ConditionType::Else,
144+
ConditionType::Also => fb::ConditionType::Also,
145+
ConditionType::End => fb::ConditionType::End,
146+
ConditionType::Group => fb::ConditionType::Group,
147+
}
148+
}
149+
}

tools/metamodel/BUILD

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,8 @@ filegroup(
5353
name = "schemas",
5454
srcs = ["schema/class_diagram.fbs"],
5555
)
56+
57+
filegroup(
58+
name = "sequence_schemas",
59+
srcs = ["schema/sequence_diagram.fbs"],
60+
)

0 commit comments

Comments
 (0)