use itertools::Itertools;
use crate::types::*;
use crate::units;
use std::hash::Hash;
use std::ops::{Deref, DerefMut};
pub trait LogicLike: std::fmt::Display + std::fmt::Debug {
fn inverse(&self) -> Self;
fn variant_eq(&self, other: &Self) -> bool;
}
#[derive(Default)]
#[derive(Debug, Clone, Copy)]
#[derive(PartialOrd)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct ChangePattern {
pub settle_down_time: units::Time,
pub transition_time: units::Time,
}
impl Ord for ChangePattern {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
match (
self.settle_down_time.partial_cmp(&other.settle_down_time),
self.transition_time.partial_cmp(&other.transition_time),
) {
(Some(c), _) => c,
(None, Some(c)) => c,
(None, None) => std::cmp::Ordering::Equal,
}
}
}
impl Hash for ChangePattern {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
float_hash(state, self.settle_down_time.value);
float_hash(state, self.transition_time.value);
}
}
impl PartialEq for ChangePattern {
fn eq(&self, other: &Self) -> bool {
float_eq(self.settle_down_time.value, other.settle_down_time.value)
&& float_eq(self.transition_time.value, other.transition_time.value)
}
}
impl Eq for ChangePattern {}
impl std::fmt::Display for ChangePattern {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut buffer1 = ryu::Buffer::new();
let mut buffer2 = ryu::Buffer::new();
write!(
f,
"({}|{})",
buffer1.format(self.settle_down_time.value),
buffer2.format(self.transition_time.value),
)
}
}
impl ChangePattern {
#[inline]
pub fn new(settle_down_time: units::Time, transition_time: units::Time) -> Self {
Self { settle_down_time, transition_time }
}
#[inline]
pub fn combine(a: &Option<Self>, b: &Option<Self>) -> Option<Self> {
match (a, b) {
(None, None) => None,
(None, Some(b)) => Some(*b),
(Some(a), None) => Some(*a),
(Some(a), Some(b)) => Some(*a),
}
}
}
#[derive(Ord, PartialOrd)]
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(strum_macros::Display, strum_macros::EnumString, strum_macros::EnumIter)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum Level {
#[strum(serialize = "h", serialize = "H", serialize = "1")]
High,
#[strum(serialize = "l", serialize = "L", serialize = "0")]
Low,
}
impl Level {
pub const H: Self = Self::High;
pub const L: Self = Self::Low;
}
impl LogicLike for Level {
#[inline]
fn inverse(&self) -> Self {
match self {
Self::Low => Self::High,
Self::High => Self::Low,
}
}
#[inline]
fn variant_eq(&self, other: &Self) -> bool {
match (self, other) {
(Level::High, Level::High) => true,
(Level::Low, Level::Low) => true,
_ => false,
}
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum Edge {
#[strum(serialize = "f", serialize = "F")]
Fall(Option<ChangePattern>),
#[strum(serialize = "r", serialize = "R")]
Rise(Option<ChangePattern>),
}
impl Edge {
pub const F: Self = Self::Fall(None);
pub const R: Self = Self::Rise(None);
}
impl std::fmt::Display for Edge {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Edge::Fall(c) => match c {
Some(c) => write!(f, "F{c}"),
None => write!(f, "F"),
},
Edge::Rise(c) => match c {
Some(c) => write!(f, "R{c}"),
None => write!(f, "R"),
},
}
}
}
impl LogicLike for Edge {
#[inline]
fn inverse(&self) -> Self {
match self {
Self::Fall(c) => Self::Rise(*c),
Self::Rise(c) => Self::Fall(*c),
}
}
#[inline]
fn variant_eq(&self, other: &Self) -> bool {
match (self, other) {
(Edge::Fall(_), Edge::Fall(_)) => true,
(Edge::Rise(_), Edge::Rise(_)) => true,
_ => false,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(strum_macros::Display)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum IllegalType {
HighImpedanceInput,
NoIdea,
RiseFallAtLevel,
}
impl IllegalType {
#[inline]
pub fn combine(a: &Option<Self>, b: &Option<Self>) -> Option<Self> {
match (a, b) {
(None, None) => None,
(None, Some(b_t)) => Some(*b_t),
(Some(a_t), None) => Some(*a_t),
(Some(a_t), Some(b_t)) => {
match (a_t, b_t) {
(a_vaild, b_vaild) => Some(*a_vaild),
}
}
}
}
}
#[derive(Debug, Clone, Copy)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter)]
#[derive(derivative::Derivative)]
#[derivative(PartialEq, Hash, Eq)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum UnInit {
#[strum(serialize = "x", serialize = "X")]
Unknown(
#[derivative(Hash = "ignore")]
#[derivative(PartialEq = "ignore")]
Option<IllegalType>,
),
#[strum(serialize = "z", serialize = "Z")]
HighImpedance,
}
impl UnInit {
pub const X: Self = Self::Unknown(None);
pub const Z: Self = Self::HighImpedance;
}
impl PartialOrd for UnInit {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for UnInit {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
match (self, other) {
(UnInit::Unknown(_), UnInit::Unknown(_)) => std::cmp::Ordering::Equal,
(UnInit::Unknown(_), UnInit::HighImpedance) => std::cmp::Ordering::Greater,
(UnInit::HighImpedance, UnInit::Unknown(_)) => std::cmp::Ordering::Less,
(UnInit::HighImpedance, UnInit::HighImpedance) => std::cmp::Ordering::Equal,
}
}
}
impl std::fmt::Display for UnInit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
UnInit::Unknown(c) => match c {
Some(c) => write!(f, "X({})", c),
None => write!(f, "X"),
},
UnInit::HighImpedance => write!(f, "Z"),
}
}
}
impl Default for UnInit {
fn default() -> Self {
Self::X
}
}
impl LogicLike for UnInit {
#[inline]
fn inverse(&self) -> Self {
*self
}
#[inline]
fn variant_eq(&self, other: &Self) -> bool {
match (self, other) {
(UnInit::Unknown(_), UnInit::Unknown(_)) => true,
(UnInit::HighImpedance, UnInit::HighImpedance) => true,
_ => false,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum Normal {
Edge(Edge),
Level(Level),
}
impl Normal {
pub const R: Self = Self::Edge(Edge::R);
pub const F: Self = Self::Edge(Edge::F);
pub const H: Self = Self::Level(Level::H);
pub const L: Self = Self::Level(Level::L);
}
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum Static {
Edge(Edge),
Level(Level),
}
impl Static {
pub const R: Self = Self::Edge(Edge::R);
pub const F: Self = Self::Edge(Edge::F);
pub const H: Self = Self::Level(Level::H);
pub const L: Self = Self::Level(Level::L);
}
impl Into<State> for Normal {
fn into(self) -> State {
match self {
Normal::Edge(s) => State::Edge(s),
Normal::Level(s) => State::Level(s),
}
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum State {
UnInit(UnInit),
Edge(Edge),
Level(Level),
}
impl std::fmt::Display for State {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
State::UnInit(s) => s.fmt(f),
State::Edge(s) => s.fmt(f),
State::Level(s) => s.fmt(f),
}
}
}
impl Default for State {
fn default() -> Self {
return Self::X;
}
}
impl LogicLike for State {
#[inline]
fn inverse(&self) -> Self {
match self {
Self::UnInit(s) => Self::UnInit(s.inverse()),
Self::Edge(s) => Self::Edge(s.inverse()),
Self::Level(s) => Self::Level(s.inverse()),
}
}
#[inline]
fn variant_eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::UnInit(a), Self::UnInit(b)) => a.variant_eq(b),
(Self::Edge(a), Self::Edge(b)) => a.variant_eq(b),
(Self::Level(a), Self::Level(b)) => a.variant_eq(b),
_ => false,
}
}
}
impl State {
pub const X: Self = Self::UnInit(UnInit::X);
pub const Z: Self = Self::UnInit(UnInit::Z);
pub const F: Self = Self::Edge(Edge::F);
pub const R: Self = Self::Edge(Edge::R);
pub const H: Self = Self::Level(Level::H);
pub const L: Self = Self::Level(Level::L);
const LIST: [Self; 6] = [Self::X, Self::Z, Self::F, Self::R, Self::H, Self::L];
#[inline]
pub fn iter() -> impl Iterator<Item = Self> {
Self::LIST.iter().copied()
}
#[inline]
pub fn get_change_pattern(&self) -> Option<ChangePattern> {
match self {
State::Edge(s) => match s {
Edge::Fall(c) => *c,
Edge::Rise(c) => *c,
},
_ => None,
}
}
#[inline]
pub fn set_change_pattern(&self, c: &Option<ChangePattern>) -> Self {
match self {
State::Edge(s) => match s {
Edge::Fall(_) => Self::Edge(Edge::Fall(*c)),
Edge::Rise(_) => Self::Edge(Edge::Rise(*c)),
},
_ => *self,
}
}
#[inline]
pub fn get_illegal_type(&self) -> Option<IllegalType> {
match self {
Self::UnInit(uninit) => match uninit {
UnInit::Unknown(t) => *t,
_ => None,
},
_ => None,
}
}
#[inline]
pub fn set_illegal_type(&self, t: &Option<IllegalType>) -> Self {
match (self, t) {
(Self::UnInit(uninit), _) => match uninit {
UnInit::Unknown(_) => Self::UnInit(UnInit::Unknown(*t)),
_ => *self,
},
_ => *self,
}
}
#[inline]
pub fn get_bgn(&self) -> Self {
match self {
State::Edge(s) => match s {
Edge::Fall(_) => Self::Level(Level::High),
Edge::Rise(_) => Self::Level(Level::Low),
},
_ => *self,
}
}
#[inline]
pub fn get_end(&self) -> Self {
match self {
State::Edge(s) => match s {
Edge::Fall(_) => Self::Level(Level::Low),
Edge::Rise(_) => Self::Level(Level::High),
},
_ => *self,
}
}
#[inline]
pub fn combine_bgn_end(bgn: &Self, end: &Self) -> Self {
match (bgn, end) {
(_, Self::Edge(_)) => {
Self::UnInit(UnInit::Unknown(Some(IllegalType::RiseFallAtLevel)))
}
(Self::Edge(_), _) => {
Self::UnInit(UnInit::Unknown(Some(IllegalType::RiseFallAtLevel)))
}
(Self::UnInit(_), Self::UnInit(_)) => *end,
(Self::UnInit(_), Self::Level(_)) => *end,
(Self::Level(_), Self::UnInit(_)) => *end,
(Self::Level(bgn), Self::Level(end)) => match (bgn, end) {
(Level::High, Level::High) => Self::Level(Level::High),
(Level::High, Level::Low) => Self::Edge(Edge::Fall(None)),
(Level::Low, Level::High) => Self::Edge(Edge::Rise(None)),
(Level::Low, Level::Low) => Self::Level(Level::Low),
},
}
}
}
#[derive(Default)]
#[derive(Debug, Clone)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Vector {
value: Vec<State>,
}
impl DerefMut for Vector {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
impl Deref for Vector {
type Target = Vec<State>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl From<Vec<State>> for Vector {
fn from(value: Vec<State>) -> Self {
Self { value }
}
}
impl Into<Vec<State>> for Vector {
fn into(self) -> Vec<State> {
self.value
}
}
impl std::fmt::Display for Vector {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self
.iter()
.fold(Ok(()), |result, state| match state.get_change_pattern() {
Some(c) => result.and_then(|_| write!(f, "{}{}", state, c)),
None => result.and_then(|_| write!(f, "{}", state)),
})
}
}
impl LogicLike for Vector {
#[inline]
fn inverse(&self) -> Self {
self
.iter()
.map(|v_state| v_state.inverse())
.collect::<Vec<State>>()
.into()
}
#[inline]
fn variant_eq(&self, other: &Self) -> bool {
if self.len() != other.len() {
return false;
}
for (idx, a) in self.iter().enumerate() {
if !a.variant_eq(&other[idx]) {
return false;
}
}
return true;
}
}
pub struct Table {
pub struct NewTable {
pub struct Searcher {