#![allow(dead_code, unused_variables)]
pub use tex_derive::Modifier;
use std::any::{Any, TypeId};
use std::collections::LinkedList;
use std::fmt::Debug;
use std::ops::Deref;
use std::rc::Rc;
pub trait Modifier: Any + Debug {
fn id(&self) -> TypeId;
fn apply(&self);
fn relax(&self);
}
#[derive(Debug, Clone)]
pub struct ModifierType(Rc<dyn Modifier>);
impl ModifierType {
pub fn new<T>(modifier: T) -> Self
where
T: Modifier,
{
Self(Rc::new(modifier))
}
pub fn id(&self) -> TypeId {
(**self).id()
}
}
impl PartialEq for ModifierType {
fn eq(&self, other: &ModifierType) -> bool {
self.id() == other.id()
}
}
impl<T: Modifier> PartialEq<T> for ModifierType {
fn eq(&self, other: &T) -> bool {
self.id() == other.id()
}
}
impl Deref for ModifierType {
type Target = dyn Modifier;
fn deref(&self) -> &dyn Modifier {
&(*self.0)
}
}
pub enum Relax {
Pop,
Cut(usize),
Target(Vec<ModifierType>),
}
#[derive(Debug)]
pub struct Format {
modifiers: Vec<ModifierType>,
stack: LinkedList<Vec<ModifierType>>,
}
impl Format {
pub fn new() -> Self {
Self {
modifiers: Vec::new(),
stack: LinkedList::new(),
}
}
pub fn apply(&mut self, modifier: ModifierType) {
modifier.apply();
self.modifiers.push(modifier);
}
pub fn relax(&mut self, op: Relax) {
match op {
Relax::Pop => {
if let Some(modifier) = self.modifiers.pop() {
modifier.relax();
}
}
Relax::Cut(count) => {
let n = match self.modifiers.len().checked_sub(count) {
Some(value) => value,
None => self.modifiers.len(),
};
self.modifiers.drain(n..).rev().for_each(|m| m.relax());
}
Relax::Target(targets) => {
for target in targets.iter() {
if let Some(idx) = self.modifiers.iter().rposition(|m| *m == *target) {
let modifier = self.modifiers.remove(idx);
modifier.relax();
}
}
}
}
}
pub fn modifiers(&self) -> &Vec<ModifierType> {
&self.modifiers
}
pub fn modifiers_mut(&mut self) -> &mut Vec<ModifierType> {
&mut self.modifiers
}
pub fn save(&mut self) {
self.stack.push_front(self.modifiers.clone());
}
pub fn load(&mut self) {
let future = self.stack.pop_front().unwrap();
let present = &self.modifiers;
present.into_iter().rev().for_each(|m| m.relax());
future.iter().for_each(|m| m.apply());
self.modifiers = future;
}
}
#[derive(Modifier, Debug, Copy, Clone)]
pub struct Null;
impl Null {
pub fn new() -> ModifierType {
ModifierType::new(Self)
}
}
#[cfg(test)]
mod test {
use super::*;
#[derive(Modifier, Debug, Copy, Clone)]
struct TestModifier;
impl TestModifier {
fn new() -> ModifierType {
ModifierType::new(Self)
}
}
#[test]
fn modifier() {
assert_eq!(Null::new(), Null::new());
assert_eq!(Null::new(), Null);
assert_ne!(Null::new(), TestModifier::new());
assert_ne!(Null::new(), TestModifier);
}
#[test]
fn format() {
let mut format = Format::new();
format.apply(Null::new());
format.save();
assert_eq!(format.modifiers(), &[Null; 1]);
format.apply(Null::new());
format.apply(Null::new());
assert_eq!(format.modifiers(), &[Null; 3]);
format.relax(Relax::Pop);
assert_eq!(format.modifiers(), &[Null; 2]);
format.load();
assert_eq!(format.modifiers(), &[Null; 1]);
format.relax(Relax::Pop);
assert_eq!(format.modifiers(), &[Null; 0]);
}
}