use crate::{NodeId, PanelId};
#[derive(Debug, thiserror::Error)]
pub enum ConstraintError {
#[error("{0} is NaN")]
IsNan(&'static str),
#[error("{0} is negative")]
IsNegative(&'static str),
#[error("{0} is infinite")]
IsInfinite(&'static str),
#[error("grow and fixed are mutually exclusive")]
GrowFixedExclusive,
#[error("min exceeds max")]
MinExceedsMax,
#[error("delta must be finite")]
DeltaNotFinite,
#[error("grid span {0} exceeds u16 max")]
GridSpanOverflow(usize),
#[error("{0} exceeds 1.0")]
ExceedsOne(&'static str),
}
#[derive(Debug, thiserror::Error)]
pub enum TreeError {
#[error("root is not set")]
RootNotSet,
#[error("root already set")]
RootAlreadySet,
#[error("root node {0} missing from arena")]
RootMissing(NodeId),
#[error("panel ID counter exhausted")]
PanelIdExhausted,
#[error("overlay ID counter exhausted")]
OverlayIdExhausted,
#[error("node arena size exceeds u32 capacity")]
ArenaOverflow,
#[error("node arena index exceeds u32 capacity")]
ArenaIndexOverflow,
#[error("node {parent} references missing child {child}")]
MissingChild {
parent: NodeId,
child: NodeId,
},
#[error("node {0} has no parent entry")]
NoParentEntry(NodeId),
#[error("parent {parent} of node {child} missing from arena")]
ParentMissing {
parent: NodeId,
child: NodeId,
},
#[error("parent_map says {parent} is parent of {child}, but children list disagrees")]
ParentChildMismatch {
parent: NodeId,
child: NodeId,
},
#[error("child {child} appears under multiple containers: {first_parent} and {second_parent}")]
ChildListedMultipleTimes {
child: NodeId,
first_parent: NodeId,
second_parent: NodeId,
},
#[error("live node {0} is disconnected from the root")]
DisconnectedNode(NodeId),
#[error("panel kind must not be empty")]
EmptyKind,
#[error("at least one kind required")]
NoKinds,
#[error("active index {active} out of bounds for {len} panels")]
ActiveOutOfBounds {
active: usize,
len: usize,
},
#[error("dashboard requires at least one card")]
DashboardNoCards,
#[error("dashboard columns must be at least 1")]
DashboardNoColumns,
#[error("dashboard min_column_width must be positive and finite")]
DashboardMinWidthInvalid,
#[error("window size must be at least 1")]
WindowSizeZero,
#[error("empty after rebuild")]
EmptyAfterRebuild,
#[error("no root")]
NoRoot,
#[error("no serializable root for snapshot")]
SnapshotNoRoot,
#[error("snapshot focused panel {0} missing from sequence")]
SnapshotFocusedMissingFromSequence(PanelId),
#[error("snapshot collapsed panel {0} missing from sequence")]
SnapshotCollapsedMissingFromSequence(PanelId),
#[error("adaptive layout requires at least one breakpoint")]
NoBreakpoints,
#[error("adaptive breakpoint width {width}px appears more than once")]
DuplicateBreakpointWidth {
width: u32,
},
#[error("snapshot tree exceeds maximum depth of {0}")]
SnapshotTooDeep(usize),
#[error("snapshot grid item span requires a panel node, got {0}")]
SnapshotSpanRequiresPanel(&'static str),
#[error("snapshot capture does not support node {0}")]
UnsupportedSnapshotNode(NodeId),
#[error("insert index {index} exceeds container length {len}")]
InsertOutOfBounds {
index: usize,
len: usize,
},
#[error("taffy error: {0}")]
TaffyError(Box<str>),
#[error("node has both 'kind' and 'type'; use one or the other")]
NodeKindAndType,
#[error("unknown node type '{0}'; expected 'row' or 'col'")]
UnknownNodeType(Box<str>),
#[error("node must have either 'kind' (panel) or 'type' (container)")]
NodeMissingKindOrType,
}
#[derive(Debug, thiserror::Error)]
pub enum ViewportError {
#[error("dimension is NaN")]
IsNan,
#[error("dimension is negative")]
IsNegative,
#[error("dimension is infinite")]
IsInfinite,
#[error("scroll value is not finite")]
ScrollNotFinite,
#[error("no saved constraints for panel {0}")]
NoSavedConstraints(PanelId),
}
#[derive(Debug, thiserror::Error)]
pub enum MutationError {
#[error("no strategy set")]
NoStrategy,
#[error("no focused panel")]
NoFocusedPanel,
#[error("focused panel has no parent")]
FocusedNoParent,
#[error("parent is not a container")]
ParentNotContainer,
#[error("panel has no parent")]
PanelNoParent,
#[error("panel is the only child")]
OnlyChild,
#[error("resize_boundary requires all siblings to be panels")]
SiblingsNotPanels,
#[error("resize_boundary requires all siblings to use grow constraints")]
SiblingsNotGrow,
#[error("no collapsed slots to uncollapse")]
NoCollapsedSlots,
#[error("slot has no saved constraints")]
SlotNoSavedConstraints,
#[error("move not supported for this layout")]
MoveNotSupported,
#[error("set_card_span requires a dashboard strategy")]
SpanNotSupported,
#[error("spatial navigation not supported — use focus_next/focus_prev")]
SpatialNavUnsupported,
}
#[derive(Debug, thiserror::Error)]
pub enum PaneError {
#[error("panel not found: {0}")]
PanelNotFound(PanelId),
#[error("invalid constraint: {0}")]
InvalidConstraint(ConstraintError),
#[error("node not found: {0}")]
NodeNotFound(NodeId),
#[error("tree validation failed: {0}")]
InvalidTree(TreeError),
#[error("invalid viewport: {0}")]
InvalidViewport(ViewportError),
#[error("invalid mutation: {0}")]
InvalidMutation(MutationError),
#[error("sequence index {0} out of bounds for length {1}")]
SequenceOutOfBounds(usize, usize),
}