1use crate::*;
2use std::borrow::Borrow;
3use std::fmt::Display;
4use std::hash::Hash;
5use std::ops::Deref;
6
7#[derive(Debug, Enum, AsRef)]
9pub enum Reducible<T> {
10 Rule(Rule<T>),
11 Reduction(Reduction<T>),
12}
13
14impl<T> Reducible<T> {
15 pub fn origin(&self) -> &Ruleset<T> {
17 match self {
18 Self::Rule(rule) => rule.ruleset(),
19 Self::Reduction(reduction) => reduction.origin(),
20 }
21 }
22}
23
24impl<T> From<Rule<T>> for Reducible<T> {
25 fn from(rule: Rule<T>) -> Self { Self::Rule(rule) }
26}
27
28impl<T> TryFrom<Reduction<T>> for Reducible<T> {
29 type Error = ();
30 fn try_from(reduction: Reduction<T>) -> Result<Self, Self::Error> {
31 if reduction.reductum().is_subrule() {
32 Ok(Self::Reduction(reduction))
33 } else {
34 Err(())
35 }
36 }
37}
38
39impl<T> Reducible<T> {
40 pub fn subrule(&self) -> &Subrule<T> {
42 match self {
43 Self::Rule(rule) => rule.subrule(),
44 Self::Reduction(reduction) => reduction.reductum().subrule().unwrap(),
45 }
46 }
47}
48
49impl<T> AsRef<Subrule<T>> for Reducible<T> {
50 fn as_ref(&self) -> &Subrule<T> { self.subrule() }
51}
52
53impl<T> Borrow<Subrule<T>> for Reducible<T> {
54 fn borrow(&self) -> &Subrule<T> { self.subrule() }
55}
56
57impl<T> Deref for Reducible<T> {
58 type Target = Subrule<T>;
59 fn deref(&self) -> &Self::Target { self.subrule() }
60}
61
62impl<T> Display for Reducible<T> {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 let precision = f.precision();
65 let string = Digest::from(self).to_string();
66 let string = &string[0..(precision.unwrap_or(string.len()))];
67 write!(f, "{string}")?;
68 Ok(())
69 }
70}
71
72impl<T> Hash for Reducible<T> {
73 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
74 match self {
75 Self::Rule(rule) => Hash::hash(rule, state),
76 Self::Reduction(reduction) => Hash::hash(reduction, state),
77 }
78 }
79}
80
81impl<T> Clone for Reducible<T> {
82 fn clone(&self) -> Self {
83 match self {
84 Self::Rule(rule) => Self::Rule(rule.clone()),
85 Self::Reduction(reduction) => Self::Reduction(reduction.clone()),
86 }
87 }
88}
89
90unsafe impl<T> Send for Reducible<T> {}
91unsafe impl<T> Sync for Reducible<T> {}