Skip to main content

jellyflow_layout/
family.rs

1use std::collections::BTreeSet;
2use std::fmt;
3
4use serde::{Deserialize, Serialize};
5
6use crate::builtin::{BuiltinLayoutEngine, engine_metadata, layered_dag_family, mind_map_family};
7use crate::engine::LayoutEngineId;
8
9/// Stable family id for DAG/layered graph layout engines.
10pub const LAYERED_DAG_LAYOUT_FAMILY_ID: &str = "layered_dag";
11/// Stable family id for mind-map layout engines.
12pub const MIND_MAP_LAYOUT_FAMILY_ID: &str = "mind_map";
13
14/// Stable identifier for a layout engine family.
15#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
16#[serde(transparent)]
17pub struct LayoutFamilyId(String);
18
19impl LayoutFamilyId {
20    /// Creates a new family id.
21    pub fn new(id: impl Into<String>) -> Self {
22        Self(id.into())
23    }
24
25    /// Returns the built-in DAG/layered family id.
26    pub fn layered_dag() -> Self {
27        Self::new(LAYERED_DAG_LAYOUT_FAMILY_ID)
28    }
29
30    /// Returns the built-in mind-map family id.
31    pub fn mind_map() -> Self {
32        Self::new(MIND_MAP_LAYOUT_FAMILY_ID)
33    }
34
35    /// Returns this id as a string slice.
36    pub fn as_str(&self) -> &str {
37        &self.0
38    }
39}
40
41impl fmt::Display for LayoutFamilyId {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        f.write_str(&self.0)
44    }
45}
46
47impl From<&str> for LayoutFamilyId {
48    fn from(value: &str) -> Self {
49        Self::new(value)
50    }
51}
52
53impl From<String> for LayoutFamilyId {
54    fn from(value: String) -> Self {
55        Self::new(value)
56    }
57}
58
59/// Metadata for a group of layout engines with related behavior.
60#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
61pub struct LayoutFamilyMetadata {
62    pub id: LayoutFamilyId,
63    pub name: String,
64}
65
66impl LayoutFamilyMetadata {
67    /// Creates family metadata.
68    pub fn new(id: impl Into<LayoutFamilyId>, name: impl Into<String>) -> Self {
69        Self {
70            id: id.into(),
71            name: name.into(),
72        }
73    }
74
75    /// Returns metadata for Jellyflow's built-in DAG/layered family.
76    pub fn layered_dag() -> Self {
77        layered_dag_family()
78    }
79
80    /// Returns metadata for Jellyflow's built-in mind-map family.
81    pub fn mind_map() -> Self {
82        mind_map_family()
83    }
84}
85
86/// Public capabilities hosts can use when choosing a layout engine.
87#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
88#[serde(rename_all = "snake_case")]
89pub enum LayoutEngineCapability {
90    /// Engine can orient its layout by [`crate::LayoutDirection`].
91    DirectionalLayout,
92    /// Engine reports routed edge points.
93    EdgeRouting,
94    /// Engine honors pinned nodes from [`crate::LayoutContext`].
95    PinnedNodes,
96    /// Engine can resolve overlap among visible nodes.
97    OverlapAvoidance,
98}
99
100/// Discovery metadata for one layout engine.
101#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
102pub struct LayoutEngineMetadata {
103    pub engine: LayoutEngineId,
104    pub family: LayoutFamilyId,
105    pub name: String,
106    #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
107    pub capabilities: BTreeSet<LayoutEngineCapability>,
108}
109
110impl LayoutEngineMetadata {
111    /// Creates engine discovery metadata.
112    pub fn new(
113        engine: impl Into<LayoutEngineId>,
114        family: impl Into<LayoutFamilyId>,
115        name: impl Into<String>,
116    ) -> Self {
117        Self {
118            engine: engine.into(),
119            family: family.into(),
120            name: name.into(),
121            capabilities: BTreeSet::new(),
122        }
123    }
124
125    /// Adds capabilities.
126    pub fn with_capabilities(
127        mut self,
128        capabilities: impl IntoIterator<Item = LayoutEngineCapability>,
129    ) -> Self {
130        self.capabilities.extend(capabilities);
131        self
132    }
133
134    /// Returns metadata for the built-in `dugong` engine.
135    pub fn dugong() -> Self {
136        engine_metadata(BuiltinLayoutEngine::Dugong)
137    }
138
139    /// Returns metadata for the built-in tidy tree engine.
140    pub fn tidy_tree() -> Self {
141        engine_metadata(BuiltinLayoutEngine::TidyTree)
142    }
143
144    /// Returns metadata for the built-in radial mind-map engine.
145    pub fn mind_map_radial() -> Self {
146        engine_metadata(BuiltinLayoutEngine::MindMapRadial)
147    }
148
149    /// Returns metadata for the built-in freeform mind-map engine.
150    pub fn mind_map_freeform() -> Self {
151        engine_metadata(BuiltinLayoutEngine::MindMapFreeform)
152    }
153}