#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MessageStyle {
SolidArrow,
DashedArrow,
SolidLine,
DashedLine,
}
impl MessageStyle {
pub fn is_dashed(self) -> bool {
matches!(self, Self::DashedArrow | Self::DashedLine)
}
pub fn has_arrow(self) -> bool {
matches!(self, Self::SolidArrow | Self::DashedArrow)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Participant {
pub id: String,
pub label: String,
}
impl Participant {
pub fn new(id: impl Into<String>) -> Self {
let id = id.into();
let label = id.clone();
Self { id, label }
}
pub fn with_label(id: impl Into<String>, label: impl Into<String>) -> Self {
Self {
id: id.into(),
label: label.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Message {
pub from: String,
pub to: String,
pub text: String,
pub style: MessageStyle,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NoteAnchor {
LeftOf(String),
RightOf(String),
Over(String),
OverPair(String, String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NoteEvent {
pub anchor: NoteAnchor,
pub text: String,
pub after_message: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Activation {
pub participant: String,
pub start_message: usize,
pub end_message: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Block {
pub kind: BlockKind,
pub branches: Vec<BlockBranch>,
pub start_message: usize,
pub end_message: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BlockBranch {
pub label: String,
pub start_message: usize,
pub end_message: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BlockKind {
Loop,
Alt,
Opt,
Par,
Critical,
Break,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AutonumberState {
On { next_value: u32 },
Off,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AutonumberChange {
pub at_message: usize,
pub state: AutonumberState,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct SequenceDiagram {
pub participants: Vec<Participant>,
pub messages: Vec<Message>,
pub notes: Vec<NoteEvent>,
pub activations: Vec<Activation>,
pub blocks: Vec<Block>,
pub autonumber_changes: Vec<AutonumberChange>,
}
impl SequenceDiagram {
pub fn participant_index(&self, id: &str) -> Option<usize> {
self.participants.iter().position(|p| p.id == id)
}
pub fn ensure_participant(&mut self, id: &str) {
if self.participant_index(id).is_none() {
self.participants.push(Participant::new(id));
}
}
}