1use nomograph_core::traits::Element;
2use nomograph_core::types::Span;
3use serde::{Deserialize, Serialize};
4use std::any::Any;
5use std::fmt;
6use std::path::{Path, PathBuf};
7use std::str::FromStr;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub enum RflpLayer {
11 Requirements,
12 Functional,
13 Logical,
14 Physical,
15}
16
17impl fmt::Display for RflpLayer {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 match self {
20 RflpLayer::Requirements => write!(f, "R"),
21 RflpLayer::Functional => write!(f, "F"),
22 RflpLayer::Logical => write!(f, "L"),
23 RflpLayer::Physical => write!(f, "P"),
24 }
25 }
26}
27
28impl FromStr for RflpLayer {
29 type Err = String;
30
31 fn from_str(s: &str) -> Result<Self, Self::Err> {
32 match s.to_uppercase().as_str() {
33 "R" | "REQUIREMENTS" => Ok(RflpLayer::Requirements),
34 "F" | "FUNCTIONAL" => Ok(RflpLayer::Functional),
35 "L" | "LOGICAL" => Ok(RflpLayer::Logical),
36 "P" | "PHYSICAL" => Ok(RflpLayer::Physical),
37 _ => Err(format!("Unknown RFLP layer: '{}'. Valid: R, F, L, P", s)),
38 }
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct SysmlElement {
44 pub qualified_name: String,
45 pub kind: String,
46 pub file_path: PathBuf,
47 pub span: Span,
48 pub doc: Option<String>,
49 pub attributes: Vec<(String, String)>,
50 #[serde(default)]
51 pub members: Vec<String>,
52 #[serde(default, skip_serializing_if = "Option::is_none")]
53 pub layer: Option<RflpLayer>,
54}
55
56impl Element for SysmlElement {
57 fn qualified_name(&self) -> &str {
58 &self.qualified_name
59 }
60
61 fn kind(&self) -> &str {
62 &self.kind
63 }
64
65 fn file_path(&self) -> &Path {
66 &self.file_path
67 }
68
69 fn span(&self) -> Span {
70 self.span.clone()
71 }
72
73 fn metadata(&self) -> &dyn Any {
74 self
75 }
76}