libreda_db/reference_access/
layout_reference_access.rs

1// Copyright (c) 2020-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6use super::hierarchy_reference_access::*;
7use crate::prelude::{Geometry, LayerInfo, LayoutBase, Rect, SimpleTransform};
8
9/// Trait that provides object-like read access to a layout structure and its elements.
10pub trait LayoutReferenceAccess: LayoutBase {
11    /// Get a cell object by its ID.
12    fn shape_ref(&self, shape_id: &Self::ShapeId) -> ShapeRef<'_, Self> {
13        ShapeRef {
14            base: self,
15            id: shape_id.clone(),
16        }
17    }
18
19    /// Get a layer object by its ID.
20    fn layer_ref(&self, layer_id: &Self::LayerId) -> LayerRef<'_, Self> {
21        LayerRef {
22            base: self,
23            id: layer_id.clone(),
24        }
25    }
26
27    /// Iterate over all layers defined in this layout.
28    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    /// Get a layer object by the layer name.
33    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    /// Get the geometric transform that describes the location of a cell instance relative to its parent.
42    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    /// Iterate over all shapes on a layer.
49    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    /// Iterate over all shapes defined in this cell.
62    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    /// Get the bounding box of the shapes on a specific layer.
69    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    /// Get the bounding box of the shapes on all layers.
74    pub fn bounding_box(&self) -> Option<Rect<L::Coord>> {
75        self.base.bounding_box(&self.id)
76    }
77}
78
79/// Reference to a layer.
80pub struct LayerRef<'a, L: LayoutBase + ?Sized> {
81    /// Reference to the parent data structure.
82    pub(super) base: &'a L,
83    /// ID of the layer.
84    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    /// Get the layer ID.
96    pub fn id(&self) -> L::LayerId {
97        self.id.clone()
98    }
99
100    /// Get the name of the layer.
101    pub fn name(&self) -> Option<L::NameType> {
102        self.layer_info().name
103    }
104
105    /// Get a reference to the layer-info structure.
106    pub fn layer_info(&self) -> LayerInfo<L::NameType> {
107        self.base.layer_info(&self.id)
108    }
109}
110
111/// Reference to a shape.
112pub struct ShapeRef<'a, L: LayoutBase + ?Sized> {
113    /// Reference to the parent data structure.
114    pub(super) base: &'a L,
115    /// ID of the shape.
116    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    /// Get the shape ID.
128    pub fn id(&self) -> L::ShapeId {
129        self.id.clone()
130    }
131
132    /// Get the cell where this shape lives.
133    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    /// Get the layer of the shape.
142    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    /// Get the cloned geometry struct representing this shape.
151    pub fn geometry_cloned(&self) -> Geometry<L::Coord> {
152        self.base.with_shape(&self.id, |_layer, geo| geo.clone())
153    }
154}