Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions plantuml/parser/integration_test/sequence_diagram/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,6 @@
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
filegroup(
name = "simple_sequence_test",
srcs = [
"simple_sequence.json",
"simple_sequence.puml",
],
visibility = ["//visibility:public"],
)

filegroup(
name = "comprehensive_sequence_test",
srcs = [
"comprehensive_sequence_test.json",
"comprehensive_sequence_test.puml",
],
visibility = ["//visibility:public"],
)

filegroup(
name = "sequence_diagram_tests",
srcs = [
":comprehensive_sequence_test",
":simple_sequence_test",
],
visibility = ["//visibility:public"],
)

filegroup(
name = "sequence_diagram_files",
srcs = glob(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"stereotype": "component"
},
{
"display_name": "RightId",
"alias": "LeftId",
"display_name": "LeftId",
"alias": "RightId",
"participant_type": "Participant",
"source_location": {
"file": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@

@startuml participant_identifier_examples

' QuotedAsId
' quoted_display_with_alias
participant "Quoted As Id" as QuotedAsId <<component>>

' IdAsQuoted
' alias_with_quoted_display
participant IdAsQuoted as "Id As Quoted" <<component>>

' IdAsId
' display_with_alias
participant LeftId as RightId <<component>>

' Quoted
' quoted_display
participant "Quoted Only" <<component>>

' Id
' alias_only
participant IdOnly <<component>>

QuotedAsId -> IdAsQuoted : callQuotedAsId()
Expand Down
14 changes: 13 additions & 1 deletion plantuml/parser/integration_test/src/test_error_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::path::Path;

use puml_parser::{
ActivityParserError, BaseParseError, ClassError, ComponentError, IncludeExpandError,
IncludeParseError, PreprocessError, ProcedureExpandError, ProcedureParseError,
IncludeParseError, PreprocessError, ProcedureExpandError, ProcedureParseError, SequenceError,
};
use puml_resolver::{
ActivityResolverError, ClassPumlResolverError, ComponentResolverError, SequenceResolverError,
Expand Down Expand Up @@ -223,6 +223,18 @@ impl ErrorView for ComponentError {
}
}

impl ErrorView for SequenceError {
fn project(&self, base_dir: &Path) -> ProjectedError {
match self {
SequenceError::Base(e) => e.project(base_dir),
SequenceError::InvalidStatement(message) => {
let _ = base_dir;
ProjectedError::new("InvalidStatement").with_field("message", message.to_string())
}
}
}
}

impl ErrorView for ComponentResolverError {
fn project(&self, _base_dir: &Path) -> ProjectedError {
match self {
Expand Down
42 changes: 30 additions & 12 deletions plantuml/parser/puml_parser/src/grammar/sequence.pest
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ stereotype_elem = {

// Participant definitions
participant_def = {
create_kw? ~ participant_type ~
(quoted_participant_as_id | participant_id_as_quoted | participant_id_as_id | quoted_participant | participant_id) ~
color_spec? ~ stereotype? ~ order_clause?
create_kw?
~ participant_type
~ participant_identifier
~ stereotype? ~ order_clause? ~ color_spec?
}

create_kw = { ^"create" }
Expand All @@ -117,14 +118,30 @@ participant_type = @{
^"entity" | ^"queue" | ^"actor") ~ &(" " | "\t" | "\n" | "\r")
}

quoted_participant_as_id = { quoted_string ~ alias_clause }
participant_id_as_quoted = { participant_id ~ alias_clause }
participant_id_as_id = { participant_id ~ alias_clause }
quoted_participant = { quoted_string }
participant_id = { CNAME }
participant_identifier = {
quoted_display_with_alias
| display_with_alias
| alias_with_quoted_display
| quoted_display
| alias_only
}

color_spec = @{ BASIC_COLOR }
// participant "Display" as Alias
quoted_display_with_alias = { quoted_string ~ ^"as" ~ NAME }

// participant Display as Alias
display_with_alias = { NAME ~ ^"as" ~ NAME }

// participant Alias as "Display"
alias_with_quoted_display = { NAME ~ ^"as" ~ quoted_string }

// participant "Display"
quoted_display = { quoted_string }

// participant Alias
alias_only = { NAME }

color_spec = @{ BASIC_COLOR }
order_clause = { ^"order" ~ signed_number }
signed_number = { "-"? ~ NUMBER }

Expand Down Expand Up @@ -159,10 +176,11 @@ message = {
async_marker = { "&" }
message_participant = {
lost_found_marker |
quoted_display_with_alias |
display_with_alias |
alias_with_quoted_display |
participant_ref |
quoted_string |
quoted_participant_as_id |
participant_id_as_quoted
quoted_string
}
lost_found_marker = { "[" ~ ("o" | "x")? | ("o" | "x")? ~ ("[" | "]") }
participant_ref = { CNAME | quoted_string }
Expand Down
19 changes: 11 additions & 8 deletions plantuml/parser/puml_parser/src/sequence_diagram/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")

rust_library(
name = "puml_parser_sequence",
Expand Down Expand Up @@ -46,14 +46,17 @@ rust_test(
],
)

# Job 1: Parse PUML file with syntax parser, output JSON
rust_binary(
name = "syntax_parse",
srcs = ["src/syntax_parse_main.rs"],
visibility = ["//visibility:public"],
rust_test(
name = "sequence_integration_test",
srcs = ["test/sequence_integration_test.rs"],
args = [
"--nocapture",
],
data = ["//plantuml/parser/puml_parser/tests/sequence_diagram:sequence_diagram_files"],
deps = [
":puml_parser_sequence",
"@crates//:serde",
"@crates//:serde_json",
"//plantuml/parser/integration_test:test_framework",
"//plantuml/parser/puml_parser:parser_core",
"//plantuml/parser/puml_utils",
],
)
8 changes: 4 additions & 4 deletions plantuml/parser/puml_parser/src/sequence_diagram/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@
// SPDX-License-Identifier: Apache-2.0
// *******************************************************************************

pub mod syntax_ast;
mod syntax_parser;
pub mod sequence_ast;
mod sequence_parser;

pub use syntax_ast::{
pub use sequence_ast::{
ActivateCmd, Arrow, CreateCmd, DeactivateCmd, DestroyCmd, ExternalEndpoint, GroupCmd,
GroupType, Message, MessageContent, ParticipantDef, ParticipantIdentifier, ParticipantType,
SeqPumlDocument, Statement,
};

pub use syntax_parser::{PumlSequenceParser, SequenceError};
pub use sequence_parser::{PumlSequenceParser, SequenceError};

/// Parse a PlantUML sequence diagram and return the document name and statements
/// This is a convenience function for backwards compatibility with tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ use std::str::FromStr;
pub use parser_core::common_ast::Arrow;

// Document structure representing a complete PlantUML sequence diagram
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SeqPumlDocument {
pub name: Option<String>,
pub statements: Vec<Statement>,
}

// Statement types used during parsing
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Statement {
DestroyCmd(DestroyCmd),
CreateCmd(CreateCmd),
Expand All @@ -38,20 +38,16 @@ pub enum Statement {
}

// Participant definitions
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ParticipantDef {
#[serde(default)]
pub is_create: bool,
pub participant_type: ParticipantType,
pub identifier: ParticipantIdentifier,
pub stereotype: Option<String>,
pub source_location: SourceLocation,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ParticipantDisplay {
pub display_name: String,
pub alias: Option<String>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct ExternalEndpoint;

Expand Down Expand Up @@ -84,66 +80,36 @@ pub enum ParticipantType {
Collections,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ParticipantIdentifier {
QuotedAsId { quoted: String, id: String },
IdAsQuoted { id: String, quoted: String },
IdAsId { id1: String, id2: String },
Quoted(String),
Id(String),
}

impl ParticipantIdentifier {
pub fn display(&self) -> ParticipantDisplay {
match self {
ParticipantIdentifier::QuotedAsId { quoted, id } => ParticipantDisplay {
display_name: quoted.clone(),
alias: Some(id.clone()),
},
ParticipantIdentifier::IdAsQuoted { id, quoted } => ParticipantDisplay {
display_name: quoted.clone(),
alias: Some(id.clone()),
},
ParticipantIdentifier::IdAsId { id1, id2 } => ParticipantDisplay {
display_name: id1.clone(),
alias: Some(id2.clone()),
},
ParticipantIdentifier::Quoted(quoted) => ParticipantDisplay {
display_name: quoted.clone(),
alias: None,
},
ParticipantIdentifier::Id(id) => ParticipantDisplay {
display_name: id.clone(),
alias: None,
},
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ParticipantIdentifier {
pub display_name: String,
pub alias: Option<String>,
}

// Destroy/Create commands
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DestroyCmd {
pub participant: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CreateCmd {
pub participant: String,
}

// Activate/Deactivate commands
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ActivateCmd {
pub participant: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DeactivateCmd {
pub participant: Option<String>,
}

// Messages (internal parsing structure)
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Message {
pub content: MessageContent,
#[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -152,7 +118,7 @@ pub struct Message {
pub source_location: SourceLocation,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum MessageContent {
WithTargets {
left: String,
Expand All @@ -168,7 +134,7 @@ pub enum ActivationType {
}

// Group commands (alt, opt, loop, etc.) - internal parsing structure
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct GroupCmd {
pub group_type: GroupType,
pub text: Option<String>,
Expand Down
Loading
Loading