ruleset/
reducible.rs

1use crate::*;
2use std::borrow::Borrow;
3use std::fmt::Display;
4use std::hash::Hash;
5use std::ops::Deref;
6
7/// Either a [`Rule`] or a [`Reduction`] with the reductum being a [`Subrule`].
8#[derive(Debug, Enum, AsRef)]
9pub enum Reducible<T> {
10	Rule(Rule<T>),
11	Reduction(Reduction<T>),
12}
13
14impl<T> Reducible<T> {
15	/// Returns a reference to the ruleset this is originated from.
16	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	/// Accesses a reference to the subrule in this variant transparently.
41	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> {}