openquiver-graph 0.1.0

OpenQuiver graph IR: nodes, pins, types. Bottom layer, no internal dependencies.
Documentation
//! Node positions on the canvas.

use std::collections::BTreeMap;

use crate::NodeName;

/// Node positions on the canvas.
///
/// Coordinates live beside the graph, not inside `Node`, for the same reason
/// comments do: they are keyed by identity and must move when a node is
/// renamed. They are kept in the same *file* as the logic, though — a separate
/// file would drift silently, and a drifted layout scatters the canvas exactly
/// when the graph most needs reading.
///
/// Integers, not floats: canvas positions snap to a grid, and exact values
/// round-trip without formatting decisions.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Layout(pub(crate) BTreeMap<NodeName, (i32, i32)>);

impl Layout {
    pub fn get(&self, name: &str) -> Option<(i32, i32)> {
        if name.is_ascii() {
            return self.0.get(name).copied();
        }
        self.0.get(&NodeName::new(name)).copied()
    }

    pub fn set(&mut self, name: NodeName, at: (i32, i32)) {
        self.0.insert(name, at);
    }

    /// Positions in canonical order, by node name.
    pub fn iter(&self) -> impl Iterator<Item = (&NodeName, (i32, i32))> {
        self.0.iter().map(|(name, at)| (name, *at))
    }

    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
}