use std::collections::BTreeSet;
use std::fmt;
use serde::{Deserialize, Serialize};
use crate::builtin::{BuiltinLayoutEngine, engine_metadata, layered_dag_family, mind_map_family};
use crate::engine::LayoutEngineId;
pub const LAYERED_DAG_LAYOUT_FAMILY_ID: &str = "layered_dag";
pub const MIND_MAP_LAYOUT_FAMILY_ID: &str = "mind_map";
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct LayoutFamilyId(String);
impl LayoutFamilyId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn layered_dag() -> Self {
Self::new(LAYERED_DAG_LAYOUT_FAMILY_ID)
}
pub fn mind_map() -> Self {
Self::new(MIND_MAP_LAYOUT_FAMILY_ID)
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for LayoutFamilyId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0)
}
}
impl From<&str> for LayoutFamilyId {
fn from(value: &str) -> Self {
Self::new(value)
}
}
impl From<String> for LayoutFamilyId {
fn from(value: String) -> Self {
Self::new(value)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LayoutFamilyMetadata {
pub id: LayoutFamilyId,
pub name: String,
}
impl LayoutFamilyMetadata {
pub fn new(id: impl Into<LayoutFamilyId>, name: impl Into<String>) -> Self {
Self {
id: id.into(),
name: name.into(),
}
}
pub fn layered_dag() -> Self {
layered_dag_family()
}
pub fn mind_map() -> Self {
mind_map_family()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum LayoutEngineCapability {
DirectionalLayout,
EdgeRouting,
PinnedNodes,
OverlapAvoidance,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LayoutEngineMetadata {
pub engine: LayoutEngineId,
pub family: LayoutFamilyId,
pub name: String,
#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
pub capabilities: BTreeSet<LayoutEngineCapability>,
}
impl LayoutEngineMetadata {
pub fn new(
engine: impl Into<LayoutEngineId>,
family: impl Into<LayoutFamilyId>,
name: impl Into<String>,
) -> Self {
Self {
engine: engine.into(),
family: family.into(),
name: name.into(),
capabilities: BTreeSet::new(),
}
}
pub fn with_capabilities(
mut self,
capabilities: impl IntoIterator<Item = LayoutEngineCapability>,
) -> Self {
self.capabilities.extend(capabilities);
self
}
pub fn dugong() -> Self {
engine_metadata(BuiltinLayoutEngine::Dugong)
}
pub fn tidy_tree() -> Self {
engine_metadata(BuiltinLayoutEngine::TidyTree)
}
pub fn mind_map_radial() -> Self {
engine_metadata(BuiltinLayoutEngine::MindMapRadial)
}
pub fn mind_map_freeform() -> Self {
engine_metadata(BuiltinLayoutEngine::MindMapFreeform)
}
}