/ cab / runtime / value / cons.rs
cons.rs
 1  use dup::Dupe;
 2  use ust::{
 3     style::StyledExt as _,
 4     terminal::tag,
 5  };
 6  
 7  use crate::{
 8     Value,
 9     value,
10  };
11  
12  #[derive(Clone, Dupe)]
13  pub struct Cons(pub Value, pub Value);
14  
15  impl tag::DisplayTags for Cons {
16     fn display_tags<'a>(&'a self, tags: &mut tag::Tags<'a>) {
17        use tag::{
18           Condition::{
19              Broken,
20              Flat,
21           },
22           Tag::{
23              Group,
24              Newline,
25              Space,
26           },
27        };
28  
29        let &Cons(ref head, ref tail) = self;
30  
31        tags.write_with(Group(40), |tags| {
32           head.display_tags(tags);
33  
34           tags.write_if(Space, Flat);
35           tags.write_if(Newline(1), Broken);
36  
37           tags.write(":".style(value::STYLE_PUNCTUATION));
38           tags.write(Space);
39  
40           tail.display_tags(tags);
41        });
42     }
43  }
44  
45  impl From<Cons> for value::Attributes {
46     fn from(cons: Cons) -> Self {
47        value::attributes::new! {
48           "fst": cons.0,
49           "snd": cons.1,
50        }
51     }
52  }
53  
54  impl TryFrom<value::Attributes> for Cons {
55     type Error = ();
56  
57     fn try_from(attrs: value::Attributes) -> Result<Self, Self::Error> {
58        let fst = attrs.get(&value::string::new!("fst")).ok_or(())?;
59        let snd = attrs.get(&value::string::new!("snd")).ok_or(())?;
60        Ok(Cons(fst.dupe(), snd.dupe()))
61     }
62  }
63  
64  #[derive(Clone, Dupe, Copy)]
65  pub struct Nil;
66  
67  impl From<Nil> for value::Attributes {
68     fn from(Nil: Nil) -> Self {
69        value::attributes::new! {
70           // TODO: Seems odd.
71           "__nil__": Value::from(Nil)
72        }
73     }
74  }