prjunnamed_netlist/
io.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use std::borrow::Cow;
use std::fmt::{Debug, Display};
use std::ops::{Index, IndexMut, Range};
use std::slice::SliceIndex;

#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct IoNet {
    pub index: u32,
}

impl IoNet {
    pub const FLOATING: IoNet = IoNet { index: u32::MAX };

    pub fn is_floating(self) -> bool {
        self.index == u32::MAX
    }
}

impl Debug for IoNet {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            IoNet { index: u32::MAX } => write!(f, "IoNet::FLOATING"),
            IoNet { index } => write!(f, "IoNet {{ index: {index} }}"),
        }
    }
}

impl Display for IoNet {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            IoNet { index: u32::MAX } => write!(f, "#_"),
            IoNet { index } => write!(f, "#{index}"),
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct IoValue {
    nets: Vec<IoNet>,
}

impl IoValue {
    pub const fn new() -> Self {
        IoValue { nets: vec![] }
    }

    pub fn from_range(range: Range<u32>) -> Self {
        Self { nets: range.map(|i| IoNet { index: i }).collect() }
    }

    pub fn floating(width: usize) -> Self {
        Self { nets: vec![IoNet::FLOATING; width] }
    }

    pub fn len(&self) -> usize {
        self.nets.len()
    }

    pub fn is_empty(&self) -> bool {
        self.nets.is_empty()
    }

    pub fn iter(&self) -> impl DoubleEndedIterator<Item = IoNet> + ExactSizeIterator + '_ {
        self.nets.iter().copied()
    }

    pub fn concat<'a>(&self, other: impl Into<Cow<'a, IoValue>>) -> Self {
        Self::from_iter(self.iter().chain(other.into().iter()))
    }

    pub fn slice(&self, range: impl std::ops::RangeBounds<usize>) -> IoValue {
        IoValue::from_iter(self[(range.start_bound().cloned(), range.end_bound().cloned())].iter().copied())
    }
}

impl From<IoNet> for IoValue {
    fn from(value: IoNet) -> Self {
        Self { nets: vec![value] }
    }
}

impl From<IoNet> for Cow<'_, IoValue> {
    fn from(value: IoNet) -> Self {
        Cow::Owned(IoValue::from(value))
    }
}

impl FromIterator<IoNet> for IoValue {
    fn from_iter<T: IntoIterator<Item = IoNet>>(iter: T) -> Self {
        IoValue { nets: iter.into_iter().collect() }
    }
}

impl<I: SliceIndex<[IoNet]>> Index<I> for IoValue {
    type Output = I::Output;

    fn index(&self, index: I) -> &Self::Output {
        &self.nets[index]
    }
}

impl<I: SliceIndex<[IoNet]>> IndexMut<I> for IoValue {
    fn index_mut(&mut self, index: I) -> &mut Self::Output {
        &mut self.nets[index]
    }
}

impl IntoIterator for &IoValue {
    type Item = IoNet;
    type IntoIter = std::vec::IntoIter<IoNet>;

    fn into_iter(self) -> Self::IntoIter {
        self.nets.clone().into_iter()
    }
}

impl IntoIterator for IoValue {
    type Item = IoNet;
    type IntoIter = std::vec::IntoIter<IoNet>;

    fn into_iter(self) -> Self::IntoIter {
        self.nets.into_iter()
    }
}

impl Extend<IoNet> for IoValue {
    fn extend<T: IntoIterator<Item = IoNet>>(&mut self, iter: T) {
        self.nets.extend(iter);
    }
}