use super::hierarchy_reference_access::*;
use crate::prelude::{Geometry, LayerInfo, LayoutBase, Rect, SimpleTransform};
pub trait LayoutReferenceAccess: LayoutBase {
fn shape_ref(&self, shape_id: &Self::ShapeId) -> ShapeRef<'_, Self> {
ShapeRef {
base: self,
id: shape_id.clone(),
}
}
fn layer_ref(&self, layer_id: &Self::LayerId) -> LayerRef<'_, Self> {
LayerRef {
base: self,
id: layer_id.clone(),
}
}
fn each_layer_ref(&self) -> Box<dyn Iterator<Item = LayerRef<'_, Self>> + '_> {
Box::new(self.each_layer().map(move |id| LayerRef { id, base: self }))
}
fn layer_ref_by_name(&self, name: &str) -> Option<LayerRef<'_, Self>> {
self.layer_by_name(name).map(|id| self.layer_ref(&id))
}
}
impl<T: LayoutBase> LayoutReferenceAccess for T {}
impl<'a, L: LayoutBase> CellInstRef<'a, L> {
pub fn get_transform(&self) -> SimpleTransform<L::Coord> {
self.base().get_transform(&self.id)
}
}
impl<'a, L: LayoutBase> CellRef<'a, L> {
pub fn each_shape_per_layer(
&self,
layer_id: &L::LayerId,
) -> impl Iterator<Item = ShapeRef<L>> + '_ {
self.base
.each_shape_id(&self.id, layer_id)
.map(move |id| ShapeRef {
id,
base: self.base,
})
}
pub fn each_shape(&self) -> impl Iterator<Item = ShapeRef<L>> + '_ {
self.base
.each_layer()
.flat_map(move |id| self.each_shape_per_layer(&id))
}
pub fn bounding_box_per_layer(&self, layer_id: &L::LayerId) -> Option<Rect<L::Coord>> {
self.base.bounding_box_per_layer(&self.id, layer_id)
}
pub fn bounding_box(&self) -> Option<Rect<L::Coord>> {
self.base.bounding_box(&self.id)
}
}
pub struct LayerRef<'a, L: LayoutBase + ?Sized> {
pub(super) base: &'a L,
pub(super) id: L::LayerId,
}
impl<'a, L: LayoutBase> Eq for LayerRef<'a, L> {}
impl<'a, L: LayoutBase> PartialEq for LayerRef<'a, L> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id && std::ptr::eq(self.base, other.base)
}
}
impl<'a, L: LayoutBase> LayerRef<'a, L> {
pub fn id(&self) -> L::LayerId {
self.id.clone()
}
pub fn name(&self) -> Option<L::NameType> {
self.layer_info().name
}
pub fn layer_info(&self) -> LayerInfo<L::NameType> {
self.base.layer_info(&self.id)
}
}
pub struct ShapeRef<'a, L: LayoutBase + ?Sized> {
pub(super) base: &'a L,
pub(super) id: L::ShapeId,
}
impl<'a, L: LayoutBase> Eq for ShapeRef<'a, L> {}
impl<'a, L: LayoutBase> PartialEq for ShapeRef<'a, L> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id && std::ptr::eq(self.base, other.base)
}
}
impl<'a, L: LayoutBase> ShapeRef<'a, L> {
pub fn id(&self) -> L::ShapeId {
self.id.clone()
}
pub fn cell(&self) -> CellRef<L> {
let id = self.base.parent_of_shape(&self.id).0;
CellRef {
id,
base: self.base,
}
}
pub fn layer(&self) -> LayerRef<L> {
let id = self.base.parent_of_shape(&self.id).1;
LayerRef {
id,
base: self.base,
}
}
pub fn geometry_cloned(&self) -> Geometry<L::Coord> {
self.base.with_shape(&self.id, |_layer, geo| geo.clone())
}
}