use super::rules::RuleBase;
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum RoutingLayerType {
Cut,
Routing,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct RoutingLayer<LayerId> {
pub id: LayerId,
pub layer_type: RoutingLayerType,
}
impl<LayerId> RoutingLayer<LayerId> {
pub fn new(id: LayerId, layer_type: RoutingLayerType) -> Self {
Self { id, layer_type }
}
pub fn as_id(&self) -> &LayerId {
&self.id
}
pub fn id(self) -> LayerId {
self.id
}
pub fn layer_type(&self) -> RoutingLayerType {
self.layer_type
}
pub fn is_via_layer(&self) -> bool {
match self.layer_type() {
RoutingLayerType::Cut => true,
RoutingLayerType::Routing => false,
}
}
pub fn is_metal_layer(&self) -> bool {
match self.layer_type() {
RoutingLayerType::Cut => false,
RoutingLayerType::Routing => true,
}
}
}
pub trait RoutingLayerStack: RuleBase {
fn layer_stack(&self) -> Vec<RoutingLayer<Self::LayerId>>;
fn layer_stack_ids(&self) -> Vec<Self::LayerId> {
self.layer_stack().into_iter().map(|l| l.id).collect()
}
fn routing_layer_stack(&self) -> Vec<Self::LayerId> {
self.layer_stack()
.into_iter()
.filter(|l| l.is_metal_layer())
.map(|l| l.id())
.collect()
}
fn via_layer_stack(&self) -> Vec<Self::LayerId> {
self.layer_stack()
.into_iter()
.filter(|l| l.is_via_layer())
.map(|l| l.id())
.collect()
}
fn get_upper_metal_layer(&self, layer: &Self::LayerId) -> Option<Self::LayerId> {
self.layer_stack()
.into_iter()
.skip_while(|l| l.as_id() != layer)
.skip(1)
.find(|l| l.is_metal_layer())
.map(|l| l.id())
}
fn get_lower_metal_layer(&self, layer: &Self::LayerId) -> Option<Self::LayerId> {
self.layer_stack()
.into_iter()
.rev()
.skip_while(|l| l.as_id() != layer)
.skip(1)
.find(|l| l.is_metal_layer())
.map(|l| l.id())
}
}