1#![allow(dead_code, unused_variables)]
2
3pub use tex_derive::Modifier;
4use std::any::{Any, TypeId};
5use std::collections::LinkedList;
6use std::fmt::Debug;
7use std::ops::Deref;
8use std::rc::Rc;
9
10pub trait Modifier: Any + Debug {
11    fn id(&self) -> TypeId;
12    fn apply(&self);
13    fn relax(&self);
14}
15
16#[derive(Debug, Clone)]
17pub struct ModifierType(Rc<dyn Modifier>);
18
19impl ModifierType {
20    pub fn new<T>(modifier: T) -> Self
21    where
22        T: Modifier,
23    {
24        Self(Rc::new(modifier))
25    }
26
27    pub fn id(&self) -> TypeId {
28        (**self).id()
29    }
30}
31
32impl PartialEq for ModifierType {
33    fn eq(&self, other: &ModifierType) -> bool {
34        self.id() == other.id()
35    }
36}
37
38impl<T: Modifier> PartialEq<T> for ModifierType {
39    fn eq(&self, other: &T) -> bool {
40        self.id() == other.id()
41    }
42}
43
44impl Deref for ModifierType {
45    type Target = dyn Modifier;
46
47    fn deref(&self) -> &dyn Modifier {
48        &(*self.0)
49    }
50}
51
52pub enum Relax {
53    Pop,
54    Cut(usize),
55    Target(Vec<ModifierType>),
56}
57
58#[derive(Debug)]
59pub struct Format {
60    modifiers: Vec<ModifierType>,
61    stack: LinkedList<Vec<ModifierType>>,
62}
63
64impl Format {
65    pub fn new() -> Self {
66        Self {
67            modifiers: Vec::new(),
68            stack: LinkedList::new(),
69        }
70    }
71
72    pub fn apply(&mut self, modifier: ModifierType) {
73        modifier.apply();
74        self.modifiers.push(modifier);
75    }
76
77    pub fn relax(&mut self, op: Relax) {
78        match op {
79            Relax::Pop => {
80                if let Some(modifier) = self.modifiers.pop() {
81                    modifier.relax();
82                }
83            }
84            Relax::Cut(count) => {
85                let n = match self.modifiers.len().checked_sub(count) {
86                    Some(value) => value,
87                    None => self.modifiers.len(),
88                };
89                self.modifiers.drain(n..).rev().for_each(|m| m.relax());
90            }
91            Relax::Target(targets) => {
92                for target in targets.iter() {
93                    if let Some(idx) = self.modifiers.iter().rposition(|m| *m == *target) {
94                        let modifier = self.modifiers.remove(idx);
95                        modifier.relax();
96                    }
97                }
98            }
99        }
100    }
101
102    pub fn modifiers(&self) -> &Vec<ModifierType> {
103        &self.modifiers
104    }
105
106    pub fn modifiers_mut(&mut self) -> &mut Vec<ModifierType> {
107        &mut self.modifiers
108    }
109
110    pub fn save(&mut self) {
111        self.stack.push_front(self.modifiers.clone());
112    }
113
114    pub fn load(&mut self) {
115        let future = self.stack.pop_front().unwrap();
116        let present = &self.modifiers;
117        present.into_iter().rev().for_each(|m| m.relax());
118        future.iter().for_each(|m| m.apply());
119        self.modifiers = future;
120    }
121}
122
123#[derive(Modifier, Debug, Copy, Clone)]
124pub struct Null;
125
126impl Null {
127    pub fn new() -> ModifierType {
128        ModifierType::new(Self)
129    }
130}
131
132#[cfg(test)]
133mod test {
134    use super::*;
135
136    #[derive(Modifier, Debug, Copy, Clone)]
137    struct TestModifier;
138
139    impl TestModifier {
140        fn new() -> ModifierType {
141            ModifierType::new(Self)
142        }
143    }
144
145    #[test]
146    fn modifier() {
147        assert_eq!(Null::new(), Null::new());
148        assert_eq!(Null::new(), Null);
149        assert_ne!(Null::new(), TestModifier::new());
150        assert_ne!(Null::new(), TestModifier);
151    }
152
153    #[test]
154    fn format() {
155        let mut format = Format::new();
156        format.apply(Null::new());
157        format.save();
158        assert_eq!(format.modifiers(), &[Null; 1]);
159
160        format.apply(Null::new());
161        format.apply(Null::new());
162        assert_eq!(format.modifiers(), &[Null; 3]);
163
164        format.relax(Relax::Pop);
165        assert_eq!(format.modifiers(), &[Null; 2]);
166
167        format.load();
168        assert_eq!(format.modifiers(), &[Null; 1]);
169
170        format.relax(Relax::Pop);
171        assert_eq!(format.modifiers(), &[Null; 0]);
172    }
173}