lispify/display/
mod.rs

1pub mod builder;
2mod display;
3
4use alloc::{
5    borrow::{Cow, ToOwned},
6    boxed::Box,
7    collections::VecDeque,
8};
9use core::{
10    fmt::{Display, Formatter},
11    ops::{Add, AddAssign, BitAnd, BitAndAssign},
12};
13use pretty_print::{
14    helpers::{PrettyPrintKind, PrettySequence},
15    PrettyBuilder, PrettyPrint, PrettyProvider, PrettyTree,
16};
17/// The lisp data structure
18#[derive(Clone, Debug)]
19pub enum Lisp {
20    /// A single atom
21    Atomic(Box<LispStyled>),
22    /// A list of atoms
23    Concat(VecDeque<Lisp>),
24    /// A list of lists
25    Sequence(VecDeque<Lisp>),
26}
27
28/// A single atom
29#[derive(Clone, Debug)]
30pub struct LispStyled {
31    text: Cow<'static, str>,
32    style: PrettyPrintKind,
33}
34
35impl Default for Lisp {
36    fn default() -> Self {
37        Self::Sequence(VecDeque::new())
38    }
39}
40
41impl<T> AddAssign<T> for Lisp
42where
43    T: Into<Lisp>,
44{
45    fn add_assign(&mut self, rhs: T) {
46        match self {
47            Lisp::Sequence(list) => list.push_back(rhs.into()),
48            _ => {
49                let mut list = VecDeque::with_capacity(2);
50                list.push_back(self.clone());
51                list.push_back(rhs.into());
52                *self = Lisp::Sequence(list);
53            }
54        }
55    }
56}
57
58impl<T> BitAndAssign<T> for Lisp
59where
60    T: Into<Lisp>,
61{
62    fn bitand_assign(&mut self, rhs: T) {
63        match self {
64            Lisp::Concat(list) => list.push_back(rhs.into()),
65            _ => {
66                let mut list = VecDeque::with_capacity(2);
67                list.push_back(self.clone());
68                list.push_back(rhs.into());
69                *self = Lisp::Concat(list);
70            }
71        }
72    }
73}
74
75impl<T> Add<T> for Lisp
76where
77    T: Into<Lisp>,
78{
79    type Output = Lisp;
80
81    fn add(mut self, rhs: T) -> Self::Output {
82        self += rhs;
83        self
84    }
85}
86
87impl<T> BitAnd<T> for Lisp
88where
89    T: Into<Lisp>,
90{
91    type Output = Lisp;
92
93    fn bitand(mut self, rhs: T) -> Self::Output {
94        self &= rhs;
95        self
96    }
97}
98
99impl<T> FromIterator<T> for Lisp
100where
101    T: Into<Lisp>,
102{
103    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
104        Lisp::Sequence(iter.into_iter().map(|x| x.into()).collect())
105    }
106}