contract_transcode/scon/
display.rs1use super::{
18 Hex,
19 Map,
20 Seq,
21 Tuple,
22 Value,
23};
24use std::fmt::{
25 Debug,
26 Display,
27 Formatter,
28 LowerHex,
29 Result,
30};
31
32struct DisplayValue<'a>(&'a Value);
34
35impl Debug for DisplayValue<'_> {
36 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
37 match &self.0 {
38 Value::Bool(boolean) => <bool as Debug>::fmt(boolean, f),
39 Value::Char(character) => <char as Debug>::fmt(character, f),
40 Value::UInt(uint) => <u128 as Display>::fmt(uint, f),
41 Value::Int(integer) => <i128 as Display>::fmt(integer, f),
42 Value::Map(map) => <DisplayMap as Debug>::fmt(&DisplayMap(map), f),
43 Value::Tuple(tuple) => <DisplayTuple as Debug>::fmt(&DisplayTuple(tuple), f),
44 Value::String(string) => <String as Display>::fmt(string, f),
45 Value::Seq(seq) => <DisplaySeq as Debug>::fmt(&DisplaySeq(seq), f),
46 Value::Hex(hex) => <Hex as Debug>::fmt(hex, f),
47 Value::Literal(literal) => <String as Display>::fmt(literal, f),
48 Value::Unit => write!(f, "()"),
49 }
50 }
51}
52
53impl Display for Value {
54 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
55 match self {
56 Value::String(string) => <String as Display>::fmt(string, f),
57 value => <DisplayValue as Debug>::fmt(&DisplayValue(value), f),
58 }
59 }
60}
61
62struct DisplayMap<'a>(&'a Map);
63
64impl Debug for DisplayMap<'_> {
65 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
66 match self.0.ident {
67 Some(ref name) => {
68 let mut builder = f.debug_struct(name);
69 for (name, value) in self.0.map.iter() {
70 builder.field(&format!("{name}"), &DisplayValue(value));
71 }
72 builder.finish()
73 }
74 None => {
75 let mut builder = f.debug_map();
76 for (name, value) in self.0.map.iter() {
77 builder.entry(name, &DisplayValue(value));
78 }
79 builder.finish()
80 }
81 }
82 }
83}
84
85struct DisplayTuple<'a>(&'a Tuple);
86
87impl Debug for DisplayTuple<'_> {
88 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
89 let name = self.0.ident.as_ref().map_or("", |s| s.as_str());
90 let mut builder = f.debug_tuple(name);
91 for value in self.0.values.iter() {
92 builder.field(&DisplayValue(value));
93 }
94 builder.finish()
95 }
96}
97
98struct DisplaySeq<'a>(&'a Seq);
99
100impl Debug for DisplaySeq<'_> {
101 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
102 let mut builder = f.debug_list();
103 for elem in &self.0.elems {
104 builder.entry(&DisplayValue(elem));
105 }
106 builder.finish()
107 }
108}
109
110impl Debug for Hex {
111 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
112 write!(f, "{self:#x}")
113 }
114}
115
116impl LowerHex for Hex {
117 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
118 if f.alternate() {
119 write!(f, "0x{}", hex::encode(&self.bytes))
120 } else {
121 write!(f, "{}", hex::encode(&self.bytes))
122 }
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn display_map() {
132 let map = Value::Map(Map::new(
133 Some("M"),
134 vec![(Value::String("a".into()), Value::UInt(1))]
135 .into_iter()
136 .collect(),
137 ));
138 assert_eq!(r#"M { a: 1 }"#, format!("{map}"), "non-alternate same line");
139 assert_eq!(
140 "M {\n a: 1,\n}",
141 format!("{map:#}"),
142 "alternate indented (pretty)"
143 );
144 }
145}