sdfparse/
path.rs

1//! The path definition in SDF.
2//!
3//! This mod is analogous to `hier_name.rs` in spef and
4//! netlistdb.
5
6use compact_str::CompactString;
7use either::Either;
8use std::hash::Hash;
9
10/// An optional bus definition.
11#[derive(Debug, PartialEq, Eq, Copy, Clone)]
12pub enum SDFBus {
13    None,
14    SingleBit(isize),
15    BitRange(isize, isize)
16}
17
18#[derive(Debug)]
19/// One instance/pin path in SDF.
20pub struct SDFPath {
21    pub path: Vec<CompactString>,
22    pub bus: SDFBus
23}
24
25/// A view of hierarchy that works with netlistdb's
26/// GeneralHierName polymorphism, except that it has a
27/// non-static reference that prevents it from being
28/// GeneralHierName.
29#[derive(Debug, Copy, Clone)]
30pub struct SDFPathHierView<'i>(&'i [CompactString]);
31
32/// A view of hierarchy that works with netlistdb's
33/// GeneralHierName polymorphism.
34/// This struct is unsafe because we transmute to it
35/// to 'static.
36#[derive(Debug, Copy, Clone)]
37pub struct SDFPathHierViewStatic(&'static [CompactString]);
38
39impl SDFPath {
40    #[inline]
41    pub fn to_cell_hier<'i>(&'i self) -> SDFPathHierView<'i> {
42        assert_eq!(self.bus, SDFBus::None);
43        SDFPathHierView(&self.path[..])
44    }
45
46    #[inline]
47    pub fn to_pin_hiers<'i>(&'i self) -> impl Iterator<Item = (
48        SDFPathHierView<'i>, &'i CompactString, Option<isize>
49    )> {
50        let hier = SDFPathHierView(&self.path[..self.path.len() - 1]);
51        let pin = &self.path[self.path.len() - 1];
52        use Either::*;
53        match self.bus {
54            SDFBus::None => Left(Some((hier, pin, None)).into_iter()),
55            SDFBus::SingleBit(i) => Left(Some((hier, pin, Some(i))).into_iter()),
56            SDFBus::BitRange(mut l, mut r) => {
57                if l > r {
58                    (l, r) = (r, l);
59                }
60                Right((l..=r).map(move |i| (hier, pin, Some(i))))
61            }
62        }
63    }
64}
65
66impl<'i, 'j> IntoIterator for &'i SDFPathHierView<'j> {
67    type Item = &'j CompactString;
68    type IntoIter = std::iter::Rev<std::slice::Iter<'j, CompactString>>;
69
70    #[inline]
71    fn into_iter(self) -> Self::IntoIter {
72        self.0.iter().rev()
73    }
74}
75
76impl<'i> IntoIterator for &'i SDFPathHierViewStatic {
77    type Item = &'i CompactString;
78    type IntoIter = std::iter::Rev<std::slice::Iter<'i, CompactString>>;
79
80    #[inline]
81    fn into_iter(self) -> Self::IntoIter {
82        self.0.iter().rev()
83    }
84}
85
86impl<'i> Hash for SDFPathHierView<'i> {
87    #[inline]
88    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
89        // reversed order, correspond to netlistdb.
90        for s in self.0.iter().rev() {
91            s.hash(state);
92        }
93    }
94}
95
96impl Hash for SDFPathHierViewStatic {
97    #[inline]
98    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
99        // reversed order, correspond to netlistdb.
100        for s in self.0.iter().rev() {
101            s.hash(state);
102        }
103    }
104}
105
106impl<'i> SDFPathHierView<'i> {
107    #[inline]
108    pub unsafe fn erase_lifetime(self) -> SDFPathHierViewStatic {
109        SDFPathHierViewStatic(std::slice::from_raw_parts(
110            self.0.as_ptr(), self.0.len()
111        ))
112    }
113}