prjunnamed_netlist/
io.rs

1use std::borrow::Cow;
2use std::fmt::{Debug, Display};
3use std::ops::{Index, IndexMut, Range};
4use std::slice::SliceIndex;
5
6#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)]
7pub struct IoNet {
8    pub index: u32,
9}
10
11impl IoNet {
12    pub const FLOATING: IoNet = IoNet { index: u32::MAX };
13
14    pub fn is_floating(self) -> bool {
15        self.index == u32::MAX
16    }
17}
18
19impl Debug for IoNet {
20    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
21        match self {
22            IoNet { index: u32::MAX } => write!(f, "IoNet::FLOATING"),
23            IoNet { index } => write!(f, "IoNet {{ index: {index} }}"),
24        }
25    }
26}
27
28impl Display for IoNet {
29    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
30        match self {
31            IoNet { index: u32::MAX } => write!(f, "#_"),
32            IoNet { index } => write!(f, "#{index}"),
33        }
34    }
35}
36
37#[derive(Clone, Debug, Eq, PartialEq, Hash)]
38pub struct IoValue {
39    nets: Vec<IoNet>,
40}
41
42impl IoValue {
43    pub const fn new() -> Self {
44        IoValue { nets: vec![] }
45    }
46
47    pub fn from_range(range: Range<u32>) -> Self {
48        Self { nets: range.map(|i| IoNet { index: i }).collect() }
49    }
50
51    pub fn floating(width: usize) -> Self {
52        Self { nets: vec![IoNet::FLOATING; width] }
53    }
54
55    pub fn len(&self) -> usize {
56        self.nets.len()
57    }
58
59    pub fn is_empty(&self) -> bool {
60        self.nets.is_empty()
61    }
62
63    pub fn iter(&self) -> impl DoubleEndedIterator<Item = IoNet> + ExactSizeIterator + '_ {
64        self.nets.iter().copied()
65    }
66
67    pub fn concat<'a>(&self, other: impl Into<Cow<'a, IoValue>>) -> Self {
68        Self::from_iter(self.iter().chain(other.into().iter()))
69    }
70
71    pub fn slice(&self, range: impl std::ops::RangeBounds<usize>) -> IoValue {
72        IoValue::from_iter(self[(range.start_bound().cloned(), range.end_bound().cloned())].iter().copied())
73    }
74}
75
76impl From<IoNet> for IoValue {
77    fn from(value: IoNet) -> Self {
78        Self { nets: vec![value] }
79    }
80}
81
82impl From<IoNet> for Cow<'_, IoValue> {
83    fn from(value: IoNet) -> Self {
84        Cow::Owned(IoValue::from(value))
85    }
86}
87
88impl FromIterator<IoNet> for IoValue {
89    fn from_iter<T: IntoIterator<Item = IoNet>>(iter: T) -> Self {
90        IoValue { nets: iter.into_iter().collect() }
91    }
92}
93
94impl<I: SliceIndex<[IoNet]>> Index<I> for IoValue {
95    type Output = I::Output;
96
97    fn index(&self, index: I) -> &Self::Output {
98        &self.nets[index]
99    }
100}
101
102impl<I: SliceIndex<[IoNet]>> IndexMut<I> for IoValue {
103    fn index_mut(&mut self, index: I) -> &mut Self::Output {
104        &mut self.nets[index]
105    }
106}
107
108impl IntoIterator for &IoValue {
109    type Item = IoNet;
110    type IntoIter = std::vec::IntoIter<IoNet>;
111
112    fn into_iter(self) -> Self::IntoIter {
113        self.nets.clone().into_iter()
114    }
115}
116
117impl IntoIterator for IoValue {
118    type Item = IoNet;
119    type IntoIter = std::vec::IntoIter<IoNet>;
120
121    fn into_iter(self) -> Self::IntoIter {
122        self.nets.into_iter()
123    }
124}
125
126impl Extend<IoNet> for IoValue {
127    fn extend<T: IntoIterator<Item = IoNet>>(&mut self, iter: T) {
128        self.nets.extend(iter);
129    }
130}