prjunnamed_pattern/
traits.rs1use std::{
2 cell::{Ref, RefCell},
3 fmt::{Debug, Display},
4};
5
6use prjunnamed_netlist::{CellRef, Const, Design, Net, Trit, Value};
7
8pub trait NetOrValue: Sized + Clone + Debug + Display {
9 fn len(&self) -> usize;
10 fn iter(&self) -> impl Iterator<Item = Net>;
11 fn as_value(&self) -> Value {
12 Value::from_iter(self.iter())
13 }
14 fn as_const(&self) -> Option<Const>;
15 fn try_from(other: impl NetOrValue) -> Option<Self>;
16
17 #[must_use]
18 fn accumulate(capture: &mut Option<Self>, net: Net) -> bool;
19}
20
21impl NetOrValue for Net {
22 fn len(&self) -> usize {
23 1
24 }
25
26 fn as_const(&self) -> Option<Const> {
27 Net::as_const(*self).map(|trit| Const::from(trit))
28 }
29
30 fn iter(&self) -> impl Iterator<Item = Net> {
31 std::iter::once(*self)
32 }
33
34 fn try_from(other: impl NetOrValue) -> Option<Self> {
35 if other.len() == 1 {
36 other.iter().next()
37 } else {
38 None
39 }
40 }
41
42 fn accumulate(capture: &mut Option<Self>, net: Net) -> bool {
43 match capture {
44 Some(captured_net) if *captured_net == net => return true,
45 Some(_) => return false,
46 None => *capture = Some(net),
47 }
48 true
49 }
50}
51
52impl NetOrValue for Value {
53 fn len(&self) -> usize {
54 Value::len(self)
55 }
56
57 fn iter(&self) -> impl Iterator<Item = Net> {
58 self.iter()
59 }
60
61 fn as_const(&self) -> Option<Const> {
62 Value::as_const(self)
63 }
64
65 fn try_from(other: impl NetOrValue) -> Option<Self> {
66 Some(Value::from_iter(other.iter()))
67 }
68
69 fn accumulate(capture: &mut Option<Self>, net: Net) -> bool {
70 match capture {
71 Some(value) => *value = value.concat(net),
72 None => *capture = Some(Value::from(net)),
73 }
74 true
75 }
76}
77
78pub trait DesignDyn {
80 fn find_cell(&self, net: Net) -> Result<(CellRef<'_>, usize), Trit>;
81
82 fn inner(&self) -> &Design;
83}
84
85impl DesignDyn for Design {
86 #[inline]
87 fn find_cell(&self, net: Net) -> Result<(CellRef<'_>, usize), Trit> {
88 Design::find_cell(self, net)
89 }
90
91 fn inner(&self) -> &Design {
92 self
93 }
94}
95
96pub struct CellCollector<'a> {
97 inner: &'a dyn DesignDyn,
98 cells: RefCell<Vec<CellRef<'a>>>,
99}
100
101impl<'a> CellCollector<'a> {
102 pub fn new(design: &'a dyn DesignDyn) -> Self {
103 Self { inner: design, cells: RefCell::new(Vec::new()) }
104 }
105
106 pub fn cells(&self) -> Ref<'_, [CellRef<'a>]> {
107 Ref::map(self.cells.borrow(), |cells| &cells[..])
108 }
109
110 pub fn clear(&self) {
111 self.cells.borrow_mut().clear();
112 }
113}
114
115impl DesignDyn for CellCollector<'_> {
116 #[inline]
117 fn find_cell(&self, net: Net) -> Result<(CellRef<'_>, usize), Trit> {
118 match self.inner.find_cell(net) {
119 Ok((cell_ref, offset)) => {
120 self.cells.borrow_mut().push(cell_ref);
121 Ok((cell_ref, offset))
122 }
123 Err(trit) => Err(trit),
124 }
125 }
126
127 fn inner(&self) -> &Design {
128 self.inner.inner()
129 }
130}