* Copyright (C) 2025-2025. Huawei Technologies Co., Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use std::{
hash::{Hash, Hasher},
sync::atomic::{AtomicU32, Ordering},
};
use serde::Serialize;
use smallvec::SmallVec;
pub type NodeKey = u32;
pub const GRAPH_NODE: NodeKey = u32::MAX;
pub const EMPTY_NODEKEY: NodeKey = u32::MAX - 1;
pub static NODEKEY_COUNTER: AtomicU32 = AtomicU32::new(0);
pub fn unique_id() -> NodeKey {
NODEKEY_COUNTER.fetch_add(1, Ordering::Relaxed)
}
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
pub struct EdgeKey {
pub source: NodeKey,
pub target: NodeKey,
}
impl Hash for EdgeKey {
fn hash<H: Hasher>(&self, state: &mut H) {
let combined = ((self.source as u64) << 32) | (self.target as u64);
combined.hash(state);
}
}
pub fn keyof(source: NodeKey, target: NodeKey) -> EdgeKey {
EdgeKey { source, target }
}
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
#[repr(u8)]
pub enum Dummy {
Root,
Edge,
EdgeProxy,
Border,
SelfEdge,
#[default]
None,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct RankLimit {
pub min: i32,
pub max: i32,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct GraphNode {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
pub dummy: Dummy,
pub rank: Option<i32>,
pub rank_limit: Option<RankLimit>,
pub order: Option<u32>,
pub border_at_left: bool,
pub active: bool,
}
impl GraphNode {
pub fn of(width: f32, height: f32) -> GraphNode {
GraphNode { width, height, active: true, ..GraphNode::default() }
}
pub fn new() -> GraphNode {
GraphNode { active: true, ..GraphNode::default() }
}
}
#[derive(Debug, Clone, Copy, Default, Serialize)]
pub struct Point {
pub x: f32,
pub y: f32,
}
impl Point {
#[inline]
pub fn new(x: f32, y: f32) -> Self {
Self { x, y }
}
}
#[derive(Debug, Clone)]
pub struct GraphEdge {
pub min_len: f32,
pub weight: f32,
pub points: Option<SmallVec<Point, 4>>,
}
impl Default for GraphEdge {
fn default() -> Self {
Self { min_len: 1.0, weight: 1.0, points: None }
}
}
impl GraphEdge {
pub fn with_weight(weight: f32) -> Self {
Self { min_len: 1.0, weight, points: None }
}
}
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub enum RankDir {
LR,
RL,
#[default]
TB,
BT,
}
#[derive(Debug, Clone, Copy)]
pub struct GraphConfig {
pub node_sep: f32,
pub edge_sep: f32,
pub rank_sep: f32,
pub rank_dir: RankDir,
pub nesting_root: Option<NodeKey>,
pub node_rank_factor: Option<f32>,
}
impl Default for GraphConfig {
fn default() -> Self {
Self {
node_sep: 50.0,
edge_sep: 20.0,
rank_sep: 50.0,
rank_dir: RankDir::TB,
nesting_root: None,
node_rank_factor: None,
}
}
}