use derive_more::{ Deref, DerefMut };
use serde::{ Serialize, Deserialize };
#[derive(Deref, DerefMut, Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Layout(pub(crate) Vec<usize>);
impl Layout {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn wrap(vec: Vec<usize>) -> Self {
Layout(vec)
}
pub fn total(&self) -> usize {
let mut total = 0usize;
for e in self.iter() { total += e }
total
}
pub(crate) fn prep(&mut self) {
if self.is_empty() {
self.push(0)
}
}
pub fn row_exists(&self, r: usize) -> anyhow::Result<()> {
if self.len() > r { Ok(()) }
else {
Err(anyhow::anyhow!("Row index exceeds number of rows in layout"))
}
}
pub fn row_is_empty(&self, r: usize) -> anyhow::Result<bool> {
self.row_exists(r)?;
let row_len = self.get(r).expect("Row exists");
Ok(*row_len == 0)
}
pub fn row_start(&self, r: usize) -> anyhow::Result<Option<usize>> {
if self.row_is_empty(r)? { return Ok(None) }
let mut start = 0usize;
for l in &self[0..r] {
start += l
}
Ok(Some(start))
}
pub fn row_end(&self, r: usize) -> anyhow::Result<Option<usize>> {
if let Some(start) = self.row_start(r)? {
let row_len = self.get(r).expect("Row exists");
Ok(Some(start + row_len - 1))
} else {
Ok(None)
}
}
pub fn row_range(&self, r: usize) -> anyhow::Result<Option<(usize, usize)>> {
if let Some(start) = self.row_start(r)? {
let end = self.row_end(r)
.expect("Row exists")
.expect("Row is not empty");
Ok(Some((start, end)))
} else {
Ok(None)
}
}
}
impl FromIterator<usize> for Layout {
fn from_iter<I: IntoIterator<Item = usize>>(iter: I) -> Self {
Layout(iter.into_iter().collect())
}
}
#[macro_export] macro_rules! layout {
() => { Layout::new() };
($($elem:expr),+ $(,)?) => {{ Layout::wrap(vec![$($elem),+]) }};
($elem:expr; $count:expr) => {{ Layout::wrap(vec![$elem; $count]) }};
}