1use std::{convert::Infallible, mem};
2
3use crate::{implemented::RustImpls, util::ContainerSizeGames, Bit, Component, Gate, GateLike};
4
5#[derive(Clone, Debug)]
6pub(crate) enum GateKind<Rust = Infallible> {
7 Custom(Component<Rust>),
8 Rust(RustImpls<Rust>),
9}
10
11impl<Rust> GateLike for GateKind<Rust>
12where
13 Rust: GateLike,
14{
15 unsafe fn compute(&mut self, input: Vec<Bit>) -> Vec<Bit> {
18 match self {
19 GateKind::Custom(component) => component.compute(input),
20 GateKind::Rust(component) => component.compute(input),
21 }
22 }
23
24 fn num_of_inputs(&self) -> usize {
25 match self {
26 Self::Custom(component) => component.num_of_inputs(),
27 Self::Rust(component) => component.num_of_inputs(),
28 }
29 }
30}
31
32impl<Rust> Gate<Rust>
33where
34 Rust: GateLike,
35{
36 pub(super) unsafe fn fill_input(&mut self, with: Bit, at: usize) -> Option<Vec<Bit>> {
43 debug_assert!(
44 self.inputs.len() > at,
45 "tried to insert at [{}], but length was {}",
46 at,
47 self.inputs.len()
48 );
49 *unsafe { self.inputs.get_unchecked_mut(at) } = with;
50 self.inputs_filled += 1;
51 if self.inputs_filled == self.inputs.len() {
52 Some(self.compute())
53 } else {
54 None
55 }
56 }
57
58 unsafe fn compute(&mut self) -> Vec<Bit> {
61 let inputs = mem::take(&mut self.inputs);
62
63 self.kind.compute(inputs)
64 }
65
66 pub(super) fn reset(&mut self, full: bool) {
67 self.inputs_filled = 0;
68 self.inputs = Vec::zeroed(self.kind.num_of_inputs());
69 if let GateKind::Custom(inner) = &mut self.kind {
70 inner.reset(full);
71 }
72 }
73}