use crate::traits::HierarchyBase;
pub trait HierarchyReferenceAccess: HierarchyBase {
fn each_cell_ref(&self) -> Box<dyn Iterator<Item = CellRef<Self>> + '_> {
Box::new(self.each_cell().map(move |id| self.cell_ref(&id)))
}
fn cell_ref(&self, cell_id: &Self::CellId) -> CellRef<'_, Self> {
CellRef {
base: self,
id: cell_id.clone(),
}
}
fn cell_instance_ref(&self, inst_id: &Self::CellInstId) -> CellInstRef<'_, Self> {
CellInstRef {
base: self,
id: inst_id.clone(),
}
}
}
impl<T: HierarchyBase> HierarchyReferenceAccess for T {}
pub struct CellRef<'a, H: HierarchyBase + ?Sized> {
pub(super) base: &'a H,
pub(super) id: H::CellId,
}
impl<'a, H: HierarchyBase> Eq for CellRef<'a, H> {}
impl<'a, H: HierarchyBase> PartialEq for CellRef<'a, H> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id && std::ptr::eq(self.base, other.base)
}
}
impl<'a, H: HierarchyBase> std::fmt::Debug for CellRef<'a, H> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "CellRef({})", self.name())
}
}
impl<'a, H: HierarchyBase> Clone for CellRef<'a, H> {
fn clone(&self) -> Self {
Self {
base: self.base,
id: self.id.clone(),
}
}
}
impl<'a, H: HierarchyBase> CellRef<'a, H> {
pub fn base(&self) -> &'_ H {
self.base
}
pub fn id(&self) -> H::CellId {
self.id.clone()
}
pub fn name(&self) -> H::NameType {
self.base.cell_name(&self.id)
}
pub fn each_cell_instance_id(&self) -> impl Iterator<Item = H::CellInstId> + '_ {
self.base.each_cell_instance(&self.id)
}
pub fn each_cell_instance(&self) -> impl Iterator<Item = CellInstRef<'a, H>> + '_ {
self.each_cell_instance_id().map(move |id| CellInstRef {
base: self.base,
id,
})
}
pub fn cell_instance_by_name(&self, name: &str) -> Option<CellInstRef<'a, H>> {
self.base
.cell_instance_by_name(&self.id, name)
.map(|id| CellInstRef {
base: self.base,
id,
})
}
pub fn each_reference_id(&self) -> impl Iterator<Item = H::CellInstId> + '_ {
self.base.each_cell_reference(&self.id)
}
pub fn each_reference(&self) -> impl Iterator<Item = CellInstRef<'a, H>> + '_ {
self.each_reference_id().map(move |id| CellInstRef {
base: self.base,
id,
})
}
pub fn num_references(&self) -> usize {
self.base.num_cell_references(&self.id)
}
pub fn each_cell_dependency(&self) -> impl Iterator<Item = CellRef<'a, H>> + '_ {
self.base
.each_cell_dependency(&self.id)
.map(move |id| CellRef {
base: self.base,
id,
})
}
pub fn num_cell_dependencies(&self) -> usize {
self.base.num_cell_dependencies(&self.id)
}
pub fn each_dependent_cell(&self) -> impl Iterator<Item = CellRef<'a, H>> + '_ {
self.base
.each_dependent_cell(&self.id)
.map(move |id| CellRef {
base: self.base,
id,
})
}
pub fn num_dependent_cells(&self) -> usize {
self.base.num_dependent_cells(&self.id)
}
pub fn num_child_instances(&self) -> usize {
self.base.num_child_instances(&self.id)
}
}
pub struct CellInstRef<'a, H: HierarchyBase + ?Sized> {
pub(super) base: &'a H,
pub(super) id: H::CellInstId,
}
impl<'a, H: HierarchyBase> Eq for CellInstRef<'a, H> {}
impl<'a, H: HierarchyBase> PartialEq for CellInstRef<'a, H> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id && std::ptr::eq(self.base, other.base)
}
}
impl<'a, H: HierarchyBase> std::fmt::Debug for CellInstRef<'a, H> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "CellInstRef({})", self.qname(":"))
}
}
impl<'a, H: HierarchyBase> CellInstRef<'a, H> {
pub fn base(&self) -> &'_ H {
self.base
}
pub fn id(&self) -> H::CellInstId {
self.id.clone()
}
pub fn name(&self) -> Option<H::NameType> {
self.base.cell_instance_name(&self.id)
}
pub fn qname(&self, separator: &str) -> String {
format!(
"{}{}{}",
self.parent().name(),
separator,
self.name()
.unwrap_or_else(|| "<unnamed>".to_string().into())
)
}
pub fn parent(&self) -> CellRef<'a, H> {
CellRef {
base: self.base,
id: self.parent_id(),
}
}
pub fn template(&self) -> CellRef<'a, H> {
CellRef {
base: self.base,
id: self.template_id(),
}
}
pub fn parent_id(&self) -> H::CellId {
self.base.parent_cell(&self.id)
}
pub fn template_id(&self) -> H::CellId {
self.base.template_cell(&self.id)
}
}