use std::cell::{RefCell, Cell};
use std::rc::{Weak, Rc};
use std::hash::{Hash, Hasher};
use std::fmt;
use super::prelude::*;
#[derive(Clone)]
pub struct Pin {
pub(super) id: usize,
pub(super) parent_circuit_id: CircuitIndex,
pub(super) parent_circuit: RefCell<Weak<Circuit>>,
name: String,
direction: Cell<Direction>,
pub(super) internal_net: RefCell<Option<Rc<Net>>>,
port: Option<(Rc<Port>, usize)>
}
impl Eq for Pin {}
impl PartialEq for Pin {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.parent_circuit_id == other.parent_circuit_id
}
}
impl Hash for Pin {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
self.parent_circuit_id.hash(state);
}
}
impl fmt::Debug for Pin {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Pin")
.field("name", &self.name)
.field("direction", &self.direction)
.field("id", &self.id)
.field("parent_circuit_id", &self.parent_circuit_id)
.finish()
}
}
impl Pin {
pub fn new<S: Into<String>>(name: S, direction: Direction) -> Self {
Pin {
id: 0,
name: name.into(),
direction: Cell::new(direction),
internal_net: Default::default(),
parent_circuit: Default::default(),
parent_circuit_id: CircuitIndex::new(0),
port: None
}
}
pub fn new_input<S: Into<String>>(name: S) -> Self {
Self::new(name, Direction::Input)
}
pub fn new_output<S: Into<String>>(name: S) -> Self {
Self::new(name, Direction::Output)
}
pub fn name(&self) -> &String {
&self.name
}
pub fn direction(&self) -> Direction {
self.direction.get()
}
pub fn set_direction(&self, direction: Direction) -> Direction {
self.direction.replace(direction)
}
pub fn id(&self) -> usize {
self.id
}
pub fn connect_net(&self, net: Option<Rc<Net>>) -> Option<Rc<Net>> {
self.parent_circuit().upgrade()
.expect("Cannot connect a pin if its parent circuit does not exist.")
.connect_pin_by_id(self.id, net)
}
pub fn disconnect_net(&self) -> Option<Rc<Net>> {
self.connect_net(None)
}
pub fn internal_net(&self) -> Option<Rc<Net>> {
self.internal_net.borrow().clone()
}
pub fn parent_circuit(&self) -> Weak<Circuit> {
self.parent_circuit.borrow().clone()
}
}