use std::ops::{Index, IndexMut};
use crate::{Node, NodeIndex, TabIndex, Tree, WindowState};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum Surface<Tab> {
Empty,
Main(Tree<Tab>),
Window(Tree<Tab>, WindowState),
}
impl<Tab> Index<NodeIndex> for Surface<Tab> {
type Output = Node<Tab>;
fn index(&self, index: NodeIndex) -> &Self::Output {
match self {
Surface::Empty => panic!("indexed on empty surface"),
Surface::Main(tree) | Surface::Window(tree, _) => &tree[index],
}
}
}
impl<Tab> IndexMut<NodeIndex> for Surface<Tab> {
fn index_mut(&mut self, index: NodeIndex) -> &mut Self::Output {
match self {
Surface::Empty => panic!("indexed on empty surface"),
Surface::Main(tree) | Surface::Window(tree, _) => &mut tree[index],
}
}
}
impl<Tab> Surface<Tab> {
pub const fn is_empty(&self) -> bool {
matches!(self, Self::Empty)
}
pub fn node_tree(&self) -> Option<&Tree<Tab>> {
match self {
Surface::Empty => None,
Surface::Main(tree) => Some(tree),
Surface::Window(tree, _) => Some(tree),
}
}
pub fn node_tree_mut(&mut self) -> Option<&mut Tree<Tab>> {
match self {
Surface::Empty => None,
Surface::Main(tree) => Some(tree),
Surface::Window(tree, _) => Some(tree),
}
}
pub fn iter_nodes(&self) -> impl Iterator<Item = &Node<Tab>> {
match self.node_tree() {
Some(tree) => tree.iter(),
None => core::slice::Iter::default(),
}
}
pub fn iter_nodes_indexed(&self) -> impl Iterator<Item = (NodeIndex, &Node<Tab>)> {
self.iter_nodes()
.enumerate()
.map(|(index, node)| (NodeIndex(index), node))
}
pub fn iter_nodes_mut(&mut self) -> impl Iterator<Item = &mut Node<Tab>> {
match self.node_tree_mut() {
Some(tree) => tree.iter_mut(),
None => core::slice::IterMut::default(),
}
}
pub fn iter_nodes_mut_indexed(&mut self) -> impl Iterator<Item = (NodeIndex, &mut Node<Tab>)> {
self.iter_nodes_mut()
.enumerate()
.map(|(index, node)| (NodeIndex(index), node))
}
pub fn iter_all_tabs(&self) -> impl Iterator<Item = ((NodeIndex, TabIndex), &Tab)> {
self.iter_nodes_indexed().flat_map(|(node_index, node)| {
node.iter_tabs_indexed()
.map(move |(tab_index, tab)| ((node_index, tab_index), tab))
})
}
pub fn iter_all_tabs_mut(&mut self) -> impl Iterator<Item = ((NodeIndex, TabIndex), &mut Tab)> {
self.iter_nodes_mut_indexed()
.flat_map(|(node_index, node)| {
node.iter_tabs_mut_indexed()
.map(move |(tab_index, tab)| ((node_index, tab_index), tab))
})
}
pub fn filter_map_tabs<F, NewTab>(&self, function: F) -> Surface<NewTab>
where
F: FnMut(&Tab) -> Option<NewTab>,
{
match self {
Surface::Empty => Surface::Empty,
Surface::Main(tree) => Surface::Main(tree.filter_map_tabs(function)),
Surface::Window(tree, window_state) => {
let tree = tree.filter_map_tabs(function);
if tree.is_empty() {
Surface::Empty
} else {
Surface::Window(tree, window_state.clone())
}
}
}
}
pub fn map_tabs<F, NewTab>(&self, mut function: F) -> Surface<NewTab>
where
F: FnMut(&Tab) -> NewTab,
{
self.filter_map_tabs(move |tab| Some(function(tab)))
}
pub fn filter_tabs<F>(&self, mut predicate: F) -> Surface<Tab>
where
F: FnMut(&Tab) -> bool,
Tab: Clone,
{
self.filter_map_tabs(move |tab| predicate(tab).then(|| tab.clone()))
}
pub fn retain_tabs<F>(&mut self, predicate: F)
where
F: FnMut(&mut Tab) -> bool,
{
if let Surface::Main(tree) | Surface::Window(tree, _) = self {
tree.retain_tabs(predicate);
if tree.is_empty() {
*self = Surface::Empty;
}
}
}
}