use crate::logic_level::LogicLevel;
use std::fmt::Debug;
pub trait Gate: Debug + Send + Sync {
fn input_pin_count(&self) -> usize;
fn output_pin_count(&self) -> usize;
fn update(&mut self, inputs: &[LogicLevel]);
fn get_output(&self, pin_index: usize) -> LogicLevel;
fn box_clone(&self) -> Box<dyn Gate>;
}
impl Clone for Box<dyn Gate> {
fn clone(&self) -> Self {
self.box_clone()
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct NotGate {
output: LogicLevel,
}
impl NotGate {
pub fn new() -> Self {
NotGate { output: LogicLevel::Low } }
}
impl Gate for NotGate {
fn input_pin_count(&self) -> usize { 1 }
fn output_pin_count(&self) -> usize { 1 }
fn update(&mut self, inputs: &[LogicLevel]) {
assert_eq!(inputs.len(), self.input_pin_count(), "Incorrect number of inputs for NOT gate");
self.output = !inputs[0];
}
fn get_output(&self, pin_index: usize) -> LogicLevel {
assert_eq!(pin_index, 0, "Invalid output pin index for NOT gate");
self.output
}
fn box_clone(&self) -> Box<dyn Gate> {
Box::new(*self)
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct AndGate {
output: LogicLevel,
}
impl AndGate {
pub fn new() -> Self {
AndGate { output: LogicLevel::Low }
}
}
impl Gate for AndGate {
fn input_pin_count(&self) -> usize { 2 }
fn output_pin_count(&self) -> usize { 1 }
fn update(&mut self, inputs: &[LogicLevel]) {
assert_eq!(inputs.len(), self.input_pin_count(), "Incorrect number of inputs for AND gate");
self.output = crate::logic_level::and(inputs[0], inputs[1]);
}
fn get_output(&self, pin_index: usize) -> LogicLevel {
assert_eq!(pin_index, 0, "Invalid output pin index for AND gate");
self.output
}
fn box_clone(&self) -> Box<dyn Gate> {
Box::new(*self)
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct OrGate {
output: LogicLevel,
}
impl OrGate {
pub fn new() -> Self {
OrGate { output: LogicLevel::Low }
}
}
impl Gate for OrGate {
fn input_pin_count(&self) -> usize { 2 }
fn output_pin_count(&self) -> usize { 1 }
fn update(&mut self, inputs: &[LogicLevel]) {
assert_eq!(inputs.len(), self.input_pin_count(), "Incorrect number of inputs for OR gate");
self.output = crate::logic_level::or(inputs[0], inputs[1]);
}
fn get_output(&self, pin_index: usize) -> LogicLevel {
assert_eq!(pin_index, 0, "Invalid output pin index for OR gate");
self.output
}
fn box_clone(&self) -> Box<dyn Gate> {
Box::new(*self)
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct NandGate {
output: LogicLevel,
}
impl NandGate {
pub fn new() -> Self {
NandGate { output: LogicLevel::High } }
}
impl Gate for NandGate {
fn input_pin_count(&self) -> usize { 2 }
fn output_pin_count(&self) -> usize { 1 }
fn update(&mut self, inputs: &[LogicLevel]) {
assert_eq!(inputs.len(), self.input_pin_count(), "Incorrect number of inputs for NAND gate");
self.output = crate::logic_level::nand(inputs[0], inputs[1]);
}
fn get_output(&self, pin_index: usize) -> LogicLevel {
assert_eq!(pin_index, 0, "Invalid output pin index for NAND gate");
self.output
}
fn box_clone(&self) -> Box<dyn Gate> {
Box::new(*self)
}
}