// SPDX-FileCopyrightText: 2024 Topola contributors // // SPDX-License-Identifier: MIT //! Module for handling Vias properties use serde::{Deserialize, Serialize}; use crate::{ drawing::{ dot::FixedDotIndex, graph::{GetMaybeNet, IsInLayer}, primitive::MakePrimitiveShape, rules::AccessRules, Drawing, }, geometry::{ compound::ManageCompounds, primitive::{DotShape, PrimitiveShape}, }, graph::{GenericIndex, GetIndex}, layout::{CompoundEntryLabel, CompoundWeight}, math::Circle, }; #[derive(Debug)] pub struct ViaRef<'a, R> { pub index: GenericIndex, drawing: &'a Drawing, } impl<'a, R> ViaRef<'a, R> { pub fn new( index: GenericIndex, drawing: &'a Drawing, ) -> Self { Self { index, drawing } } pub fn dots(&self) -> impl Iterator + '_ { self.drawing .geometry() .compound_members(self.index.into()) .map(|(_, index)| FixedDotIndex::new(index.index())) } } impl GetMaybeNet for ViaRef<'_, R> { fn maybe_net(&self) -> Option { self.drawing.compound_weight(self.index.into()).maybe_net() } } impl MakePrimitiveShape for ViaRef<'_, R> { fn shape(&self) -> PrimitiveShape { if let CompoundWeight::Via(weight) = self.drawing.compound_weight(self.index.into()) { weight.shape() } else { unreachable!(); } } } #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub struct ViaWeight { pub from_layer: usize, pub to_layer: usize, pub circle: Circle, pub maybe_net: Option, } impl From> for GenericIndex { fn from(via: GenericIndex) -> Self { GenericIndex::::new(via.index()) } } impl GetMaybeNet for ViaWeight { fn maybe_net(&self) -> Option { self.maybe_net } } impl IsInLayer for ViaWeight { fn is_in_layer(&self, layer: usize) -> bool { (self.from_layer..=self.to_layer).contains(&layer) } fn is_in_any_layer_of(&self, layers: &[bool]) -> bool { layers .get(self.from_layer..=core::cmp::min(self.to_layer, layers.len())) .map(|i| i.iter().any(|j| *j)) .unwrap_or(false) } } impl MakePrimitiveShape for ViaWeight { fn shape(&self) -> PrimitiveShape { DotShape { circle: self.circle, } .into() } }