mod builders;
mod xml;
#[cfg(test)]
mod tests;
#[cfg(test)]
mod tests_builders;
use crate::shapes::Shape;
use crate::units::{Emu, ShapeId};
#[derive(Debug, Clone, PartialEq)]
pub struct GroupShape {
pub shape_id: ShapeId,
pub name: String,
pub left: Emu,
pub top: Emu,
pub width: Emu,
pub height: Emu,
pub rotation: f64,
pub shapes: Vec<Shape>,
}
impl GroupShape {
pub fn add_shape(&mut self, shape: Shape) {
self.shapes.push(shape);
}
#[must_use]
pub fn len(&self) -> usize {
self.shapes.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.shapes.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &Shape> {
self.shapes.iter()
}
#[must_use]
pub fn max_shape_id(&self) -> ShapeId {
self.shapes
.iter()
.map(|s| match s {
Shape::GroupShape(g) => g.max_shape_id().max(g.shape_id),
other => other.shape_id(),
})
.max()
.unwrap_or(ShapeId(0))
}
pub(crate) fn next_shape_id(&self) -> ShapeId {
let max = self.max_shape_id().max(self.shape_id);
ShapeId(max.0 + 1)
}
pub(crate) fn count_shapes_with_prefix(&self, prefix: &str) -> u32 {
let count = self
.shapes
.iter()
.filter(|s| s.name().starts_with(prefix))
.count();
u32::try_from(count).unwrap_or(u32::MAX)
}
}
impl std::fmt::Display for GroupShape {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "GroupShape(\"{}\")", self.name)
}
}