Skip to main content

alux_shape_text/
text.rs

1//! Renders a shape as the text that describes it.
2
3use alux_shape::{FieldAlg, ShapeAlg, Sorts, Words};
4
5/// Renders a shape as text, spelling names as the words they are, joined by `_`.
6#[derive(Debug, Clone, Copy, Default)]
7pub struct TextShape;
8
9/// Joins a name's words as this interpretation spells them.
10fn spell(words: Words<'_>) -> String {
11    words.join("_")
12}
13
14impl Sorts for TextShape {
15    type Ty = String;
16    type Field = String;
17}
18
19impl ShapeAlg for TextShape {
20    fn truth(&self) -> String {
21        "bool".into()
22    }
23
24    fn unit(&self) -> String {
25        "unit".into()
26    }
27
28    fn text(&self) -> String {
29        "text".into()
30    }
31
32    fn literal(&self, text: &str) -> String {
33        format!("\"{text}\"")
34    }
35
36    fn name_word(&self, words: Words<'_>) -> String {
37        format!("\"{}\"", spell(words))
38    }
39
40    fn int(&self, signed: bool, bits: u16) -> String {
41        let sign = if signed { 'i' } else { 'u' };
42
43        format!("{sign}{bits}")
44    }
45
46    fn float(&self, bits: u16) -> String {
47        format!("f{bits}")
48    }
49
50    fn bytes(&self, len: Option<usize>) -> String {
51        match len {
52            Some(len) => format!("bytes<{len}>"),
53            None => "bytes".into(),
54        }
55    }
56
57    fn hex(&self, item: String) -> String {
58        format!("hex {item}")
59    }
60
61    fn decimal(&self, item: String) -> String {
62        format!("decimal {item}")
63    }
64
65    fn base64(&self, item: String) -> String {
66        format!("base64 {item}")
67    }
68
69    fn opt(&self, item: String) -> String {
70        format!("{item}?")
71    }
72
73    fn seq(&self, item: String) -> String {
74        format!("[{item}]")
75    }
76
77    fn map(&self, key: String, value: String) -> String {
78        format!("{{{key}: {value}}}")
79    }
80
81    fn product(&self, fields: Vec<String>) -> String {
82        format!("{{ {} }}", fields.join(", "))
83    }
84
85    fn choice(&self, alternatives: Vec<String>) -> String {
86        format!("({})", alternatives.join(" | "))
87    }
88
89    fn named(&self, words: Words, body: String) -> String {
90        format!("{} {body}", spell(words))
91    }
92
93    fn reference(&self, words: Words<'_>) -> String {
94        spell(words)
95    }
96}
97
98impl FieldAlg for TextShape {
99    fn field(&self, words: Words, shape: String) -> String {
100        format!("{}: {shape}", spell(words))
101    }
102
103    fn merge(&self, shape: String) -> String {
104        format!("..{shape}")
105    }
106}