libreda_db/reference_access/
layout_reference_access.rs1use super::hierarchy_reference_access::*;
7use crate::prelude::{Geometry, LayerInfo, LayoutBase, Rect, SimpleTransform};
8
9pub trait LayoutReferenceAccess: LayoutBase {
11 fn shape_ref(&self, shape_id: &Self::ShapeId) -> ShapeRef<'_, Self> {
13 ShapeRef {
14 base: self,
15 id: shape_id.clone(),
16 }
17 }
18
19 fn layer_ref(&self, layer_id: &Self::LayerId) -> LayerRef<'_, Self> {
21 LayerRef {
22 base: self,
23 id: layer_id.clone(),
24 }
25 }
26
27 fn each_layer_ref(&self) -> Box<dyn Iterator<Item = LayerRef<'_, Self>> + '_> {
29 Box::new(self.each_layer().map(move |id| LayerRef { id, base: self }))
30 }
31
32 fn layer_ref_by_name(&self, name: &str) -> Option<LayerRef<'_, Self>> {
34 self.layer_by_name(name).map(|id| self.layer_ref(&id))
35 }
36}
37
38impl<T: LayoutBase> LayoutReferenceAccess for T {}
39
40impl<'a, L: LayoutBase> CellInstRef<'a, L> {
41 pub fn get_transform(&self) -> SimpleTransform<L::Coord> {
43 self.base().get_transform(&self.id)
44 }
45}
46
47impl<'a, L: LayoutBase> CellRef<'a, L> {
48 pub fn each_shape_per_layer(
50 &self,
51 layer_id: &L::LayerId,
52 ) -> impl Iterator<Item = ShapeRef<L>> + '_ {
53 self.base
54 .each_shape_id(&self.id, layer_id)
55 .map(move |id| ShapeRef {
56 id,
57 base: self.base,
58 })
59 }
60
61 pub fn each_shape(&self) -> impl Iterator<Item = ShapeRef<L>> + '_ {
63 self.base
64 .each_layer()
65 .flat_map(move |id| self.each_shape_per_layer(&id))
66 }
67
68 pub fn bounding_box_per_layer(&self, layer_id: &L::LayerId) -> Option<Rect<L::Coord>> {
70 self.base.bounding_box_per_layer(&self.id, layer_id)
71 }
72
73 pub fn bounding_box(&self) -> Option<Rect<L::Coord>> {
75 self.base.bounding_box(&self.id)
76 }
77}
78
79pub struct LayerRef<'a, L: LayoutBase + ?Sized> {
81 pub(super) base: &'a L,
83 pub(super) id: L::LayerId,
85}
86
87impl<'a, L: LayoutBase> Eq for LayerRef<'a, L> {}
88impl<'a, L: LayoutBase> PartialEq for LayerRef<'a, L> {
89 fn eq(&self, other: &Self) -> bool {
90 self.id == other.id && std::ptr::eq(self.base, other.base)
91 }
92}
93
94impl<'a, L: LayoutBase> LayerRef<'a, L> {
95 pub fn id(&self) -> L::LayerId {
97 self.id.clone()
98 }
99
100 pub fn name(&self) -> Option<L::NameType> {
102 self.layer_info().name
103 }
104
105 pub fn layer_info(&self) -> LayerInfo<L::NameType> {
107 self.base.layer_info(&self.id)
108 }
109}
110
111pub struct ShapeRef<'a, L: LayoutBase + ?Sized> {
113 pub(super) base: &'a L,
115 pub(super) id: L::ShapeId,
117}
118
119impl<'a, L: LayoutBase> Eq for ShapeRef<'a, L> {}
120impl<'a, L: LayoutBase> PartialEq for ShapeRef<'a, L> {
121 fn eq(&self, other: &Self) -> bool {
122 self.id == other.id && std::ptr::eq(self.base, other.base)
123 }
124}
125
126impl<'a, L: LayoutBase> ShapeRef<'a, L> {
127 pub fn id(&self) -> L::ShapeId {
129 self.id.clone()
130 }
131
132 pub fn cell(&self) -> CellRef<L> {
134 let id = self.base.parent_of_shape(&self.id).0;
135 CellRef {
136 id,
137 base: self.base,
138 }
139 }
140
141 pub fn layer(&self) -> LayerRef<L> {
143 let id = self.base.parent_of_shape(&self.id).1;
144 LayerRef {
145 id,
146 base: self.base,
147 }
148 }
149
150 pub fn geometry_cloned(&self) -> Geometry<L::Coord> {
152 self.base.with_shape(&self.id, |_layer, geo| geo.clone())
153 }
154}