spefparse 0.2.0

SPEF parasitics parser
Documentation
//! Hierarchical name implementation for SPEF parser.
//!
//! With special focus on interoperability with NetlistDB.

use compact_str::CompactString;
use std::hash::Hash;

/// Hierarchical name.
/// 
/// Unlike the NetlistDB's tree-like structure, this one
/// adopts a simple Vec.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct HierName(pub Vec<CompactString>);

/// Reverse iterator implementation for hierarchical name,
/// yielding cell names from the bottom to the top.
type HierNameRevIter<'i> = std::iter::Rev<std::slice::Iter<'i, CompactString>>;

impl<'i> IntoIterator for &'i HierName {
    type Item = &'i CompactString;
    type IntoIter = HierNameRevIter<'i>;

    #[inline]
    fn into_iter(self) -> HierNameRevIter<'i> {
        self.0.iter().rev()
    }
}

impl HierName {
    #[inline]
    pub fn iter(&self) -> HierNameRevIter {
        (&self).into_iter()
    }
}

/// Hashing a HierName.
/// 
/// Our guarantee here is that
/// `Hash(HierName[a/b/c]) :== Hash(c, b, a)`.
/// 
/// This is essential for different HierName implementations
/// to agree with each other on hash values.
/// Especially, to conform with NetlistDB's implementation.
///
/// For example, we have a `Vec` here in SPEF parser's
/// HierName implementation, but we cannot use derived Hash
/// on it. -- because hash of a `Vec` is the same as a slice,
/// which not only prefixes the hash with a length parameter,
/// but also hashes it forward instead of backward.
///
/// Thus we implement it by ourselves.
impl Hash for HierName {
    #[inline]
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        for s in self.iter() {
            s.hash(state);
        }
    }
}