Skip to content

Commit e08f0da

Browse files
activity diagram serializer
1 parent b08a181 commit e08f0da

7 files changed

Lines changed: 456 additions & 4 deletions

File tree

plantuml/parser/puml_cli/src/main.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@ use std::rc::Rc;
2323

2424
use puml_lobster::{write_lobster_to_file, LobsterModel};
2525
use puml_parser::{
26-
DiagramParser, ErrorLocation, Preprocessor, PumlClassParser, PumlComponentParser,
27-
PumlSequenceParser,
26+
DiagramParser, ErrorLocation, Preprocessor, PumlActivityParser, PumlClassParser,
27+
PumlComponentParser, PumlSequenceParser,
2828
};
2929
use puml_resolver::{
30-
ClassResolver, DiagramResolver, ElementResolver, LogicElement, SequenceResolver, SequenceTree,
30+
ActivityDiagram, ActivityResolver, ClassResolver, DiagramResolver, ElementResolver,
31+
LogicElement, SequenceResolver, SequenceTree,
32+
};
33+
use puml_serializer::{
34+
ActivitySerializer, ClassSerializer, ComponentSerializer, SequenceSerializer,
3135
};
32-
use puml_serializer::{ClassSerializer, ComponentSerializer, SequenceSerializer};
3336
use puml_utils::{write_fbs_to_file, write_json_to_file, LogLevel};
3437

3538
/// CLI wrapper for LogLevel that implements ValueEnum
@@ -99,6 +102,7 @@ struct Args {
99102
#[derive(Copy, Clone, ValueEnum, Debug)]
100103
enum DiagramType {
101104
None,
105+
Activity,
102106
Component,
103107
Deployment,
104108
Class,
@@ -108,6 +112,7 @@ enum DiagramType {
108112
#[allow(dead_code)] // Class and Sequence variants are WIP
109113
#[derive(Debug, Serialize)]
110114
enum ParsedDiagram {
115+
Activity(puml_parser::RawActivityDiagram),
111116
Component(puml_parser::CompPumlDocument),
112117
Class(puml_parser::ClassUmlFile),
113118
Sequence(puml_parser::SeqPumlDocument),
@@ -191,6 +196,7 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
191196
let lobster_model = match &logic_result {
192197
ResolvedDiagram::Component(model) => LobsterModel::Component(model),
193198
ResolvedDiagram::Class(model) => LobsterModel::Class(model),
199+
ResolvedDiagram::Activity(_) => LobsterModel::Empty,
194200
ResolvedDiagram::Sequence(_) => LobsterModel::Empty,
195201
};
196202
write_lobster_to_file(lobster_model, path, ldir)?;
@@ -208,6 +214,9 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
208214

209215
fn serialize_resolved_diagram(resolved_content: &ResolvedDiagram, source_file: &str) -> Vec<u8> {
210216
match resolved_content {
217+
ResolvedDiagram::Activity(resolved_content) => {
218+
ActivitySerializer::serialize(resolved_content, source_file)
219+
}
211220
ResolvedDiagram::Component(resolved_content) => {
212221
ComponentSerializer::serialize(resolved_content, source_file)
213222
}
@@ -222,6 +231,7 @@ fn serialize_resolved_diagram(resolved_content: &ResolvedDiagram, source_file: &
222231

223232
#[derive(Debug, Serialize)]
224233
pub enum ResolvedDiagram {
234+
Activity(ActivityDiagram),
225235
Component(HashMap<String, LogicElement>),
226236
Class(class_diagram::ClassDiagram),
227237
Sequence(SequenceTree),
@@ -231,6 +241,10 @@ fn resolve_parsed_diagram(
231241
parsed_content: ParsedDiagram,
232242
) -> Result<ResolvedDiagram, Box<dyn std::error::Error>> {
233243
match parsed_content {
244+
ParsedDiagram::Activity(parsed_content) => {
245+
let mut resolver = ActivityResolver::new();
246+
puml_resolver(&mut resolver, &parsed_content).map(ResolvedDiagram::Activity)
247+
}
234248
ParsedDiagram::Component(parsed_content) => {
235249
let mut resolver = ElementResolver::new();
236250
puml_resolver(&mut resolver, &parsed_content).map(ResolvedDiagram::Component)
@@ -289,6 +303,10 @@ fn parse_puml_file(
289303
diagram_type: DiagramType,
290304
) -> Result<ParsedDiagram, Box<dyn std::error::Error>> {
291305
match diagram_type {
306+
DiagramType::Activity => {
307+
parse_with_parser(&mut PumlActivityParser, path, content, log_level)
308+
.map(ParsedDiagram::Activity)
309+
}
292310
DiagramType::Component | DiagramType::Deployment => {
293311
parse_with_parser(&mut PumlComponentParser, path, content, log_level)
294312
.map(ParsedDiagram::Component)
@@ -326,6 +344,18 @@ fn parse_in_order(
326344
}
327345
}
328346

347+
match PumlActivityParser.parse_file(path, content, log_level) {
348+
Ok(doc) => {
349+
debug!("Successfully detected as Activity diagram");
350+
return Ok(ParsedDiagram::Activity(doc));
351+
}
352+
Err(e) => {
353+
let loc = e.error_location();
354+
debug!("Activity parser failed at {:?}: {}", loc, e);
355+
attempts.push(("Activity", Box::new(e), loc));
356+
}
357+
}
358+
329359
match PumlClassParser.parse_file(path, content, log_level) {
330360
Ok(doc) => {
331361
debug!("Successfully detected as Class diagram");

plantuml/parser/puml_serializer/BUILD

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ rust_library(
1717
srcs = ["src/lib.rs"],
1818
visibility = ["//plantuml/parser:__subpackages__"],
1919
deps = [
20+
":activity_serializer",
2021
":class_serializer",
2122
":component_serializer",
2223
":sequence_serializer",
2324
],
2425
)
2526

27+
alias(
28+
name = "activity_serializer",
29+
actual = "//plantuml/parser/puml_serializer/src/serialize:puml_serialize_activity",
30+
visibility = ["//plantuml/parser:__subpackages__"],
31+
)
32+
2633
alias(
2734
name = "component_serializer",
2835
actual = "//plantuml/parser/puml_serializer/src/serialize:puml_serialize_component",

plantuml/parser/puml_serializer/src/fbs/BUILD

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ rust_library(
4141
],
4242
)
4343

44+
flatbuffer_library_public(
45+
name = "activity_fbs_codegen",
46+
srcs = [
47+
"activity.fbs",
48+
],
49+
outs = [
50+
"activity_generated.rs",
51+
],
52+
flatc_args = [],
53+
language_flag = "--rust",
54+
visibility = ["//plantuml/parser:__subpackages__"],
55+
)
56+
57+
rust_library(
58+
name = "activity_fbs",
59+
srcs = [
60+
":activity_fbs_codegen",
61+
],
62+
# Generated code from flatc - suppress all lints we can't fix
63+
rustc_flags = ["--cap-lints=allow"],
64+
visibility = [
65+
"//visibility:public",
66+
],
67+
deps = [
68+
"@crates//:flatbuffers",
69+
],
70+
)
71+
4472
flatbuffer_library_public(
4573
name = "class_fbs_codegen",
4674
srcs = [
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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+
namespace activity;
15+
16+
enum ControlKind:byte {
17+
Stop,
18+
Kill,
19+
Detach,
20+
Break,
21+
Continue
22+
}
23+
24+
table IfDisplay {
25+
then_label:string;
26+
else_label:string;
27+
}
28+
29+
table LoopDisplay {
30+
continue_label:string;
31+
exit_label:string;
32+
}
33+
34+
table TitleNode {
35+
text:string;
36+
}
37+
38+
table ActionNode {
39+
label:string;
40+
}
41+
42+
table BackwardNode {
43+
label:string;
44+
}
45+
46+
table ControlNode {
47+
kind:ControlKind = Stop;
48+
}
49+
50+
table IfNode {
51+
condition:string;
52+
body:[ActivityStmt];
53+
else_branch:[ActivityStmt];
54+
display:IfDisplay;
55+
}
56+
57+
table WhileNode {
58+
condition:string;
59+
body:[ActivityStmt];
60+
backward:BackwardNode;
61+
display:LoopDisplay;
62+
}
63+
64+
table RepeatWhileNode {
65+
body:[ActivityStmt];
66+
condition:string;
67+
backward:BackwardNode;
68+
display:LoopDisplay;
69+
}
70+
71+
union ActivityStmtValue {
72+
TitleNode,
73+
ActionNode,
74+
IfNode,
75+
WhileNode,
76+
RepeatWhileNode,
77+
ControlNode
78+
}
79+
80+
table ActivityStmt {
81+
value:ActivityStmtValue;
82+
}
83+
84+
table ActivityDiagram {
85+
name:string;
86+
statements:[ActivityStmt];
87+
source_file:string;
88+
}
89+
90+
root_type ActivityDiagram;

plantuml/parser/puml_serializer/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// SPDX-License-Identifier: Apache-2.0
1212
// *******************************************************************************
1313

14+
pub use activity_serializer::ActivitySerializer;
1415
pub use class_serializer::ClassSerializer;
1516
pub use component_serializer::ComponentSerializer;
1617
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
@@ -12,6 +12,21 @@
1212
# *******************************************************************************
1313
load("@rules_rust//rust:defs.bzl", "rust_library")
1414

15+
rust_library(
16+
name = "puml_serialize_activity",
17+
srcs = [
18+
"activity_serializer.rs",
19+
],
20+
crate_name = "activity_serializer",
21+
crate_root = "activity_serializer.rs",
22+
visibility = ["//plantuml/parser:__subpackages__"],
23+
deps = [
24+
"//plantuml/parser/puml_resolver:activity_resolver",
25+
"//plantuml/parser/puml_serializer/src/fbs:activity_fbs",
26+
"@crates//:flatbuffers",
27+
],
28+
)
29+
1530
rust_library(
1631
name = "puml_serialize_component",
1732
srcs = [

0 commit comments

Comments
 (0)