databend_driver_core/value/format/
display.rs1use crate::_macro_internal::Value;
16use crate::value::base::{DAYS_FROM_CE, TIMESTAMP_FORMAT, TIMESTAMP_TIMEZONE_FORMAT};
17use crate::value::NumberValue;
18use chrono::NaiveDate;
19use ethnum::i256;
20use std::fmt::Write;
21
22impl std::fmt::Display for Value {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 self.display_value(f, true)
25 }
26}
27
28impl std::fmt::Display for NumberValue {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 NumberValue::Int8(i) => write!(f, "{i}"),
32 NumberValue::Int16(i) => write!(f, "{i}"),
33 NumberValue::Int32(i) => write!(f, "{i}"),
34 NumberValue::Int64(i) => write!(f, "{i}"),
35 NumberValue::UInt8(i) => write!(f, "{i}"),
36 NumberValue::UInt16(i) => write!(f, "{i}"),
37 NumberValue::UInt32(i) => write!(f, "{i}"),
38 NumberValue::UInt64(i) => write!(f, "{i}"),
39 NumberValue::Float32(i) => write!(f, "{i}"),
40 NumberValue::Float64(i) => write!(f, "{i}"),
41 NumberValue::Decimal64(v, s) => {
42 write!(f, "{}", display_decimal_128(*v as i128, s.scale))
43 }
44 NumberValue::Decimal128(v, s) => write!(f, "{}", display_decimal_128(*v, s.scale)),
45 NumberValue::Decimal256(v, s) => write!(f, "{}", display_decimal_256(*v, s.scale)),
46 }
47 }
48}
49
50impl Value {
51 pub fn display_value(&self, f: &mut std::fmt::Formatter<'_>, raw: bool) -> std::fmt::Result {
54 match self {
55 Value::Null => write!(f, "NULL"),
56 Value::EmptyArray => write!(f, "[]"),
57 Value::EmptyMap => write!(f, "{{}}"),
58 Value::Boolean(b) => {
59 if *b {
60 write!(f, "true")
61 } else {
62 write!(f, "false")
63 }
64 }
65 Value::Number(n) => write!(f, "{n}"),
66 Value::Binary(s) => write!(f, "{}", hex::encode_upper(s)),
67 Value::String(s)
68 | Value::Bitmap(s)
69 | Value::Variant(s)
70 | Value::Interval(s)
71 | Value::Geometry(s)
72 | Value::Geography(s) => {
73 if raw {
74 write!(f, "{s}")
75 } else {
76 write!(f, "'{s}'")
77 }
78 }
79 Value::Timestamp(dt) => {
80 let formatted = dt.strftime(TIMESTAMP_FORMAT);
81 if raw {
82 write!(f, "{formatted}")
83 } else {
84 write!(f, "'{formatted}'")
85 }
86 }
87 Value::TimestampTz(dt) => {
88 let formatted = dt.strftime(TIMESTAMP_TIMEZONE_FORMAT);
89 if raw {
90 write!(f, "{formatted}")
91 } else {
92 write!(f, "'{formatted}'")
93 }
94 }
95 Value::Date(i) => {
96 let days = i + DAYS_FROM_CE;
97 let d = NaiveDate::from_num_days_from_ce_opt(days).unwrap_or_default();
98 if raw {
99 write!(f, "{d}")
100 } else {
101 write!(f, "'{d}'")
102 }
103 }
104 Value::Array(vals) => {
105 write!(f, "[")?;
106 for (i, val) in vals.iter().enumerate() {
107 if i > 0 {
108 write!(f, ",")?;
109 }
110 val.display_value(f, false)?;
111 }
112 write!(f, "]")?;
113 Ok(())
114 }
115 Value::Map(kvs) => {
116 write!(f, "{{")?;
117 for (i, (key, val)) in kvs.iter().enumerate() {
118 if i > 0 {
119 write!(f, ",")?;
120 }
121 key.display_value(f, false)?;
122 write!(f, ":")?;
123 val.display_value(f, false)?;
124 }
125 write!(f, "}}")?;
126 Ok(())
127 }
128 Value::Tuple(vals) => {
129 write!(f, "(")?;
130 for (i, val) in vals.iter().enumerate() {
131 if i > 0 {
132 write!(f, ",")?;
133 }
134 val.display_value(f, false)?;
135 }
136 write!(f, ")")?;
137 Ok(())
138 }
139 Value::Vector(vals) => {
140 write!(f, "[")?;
141 for (i, val) in vals.iter().enumerate() {
142 if i > 0 {
143 write!(f, ",")?;
144 }
145 write!(f, "{val}")?;
146 }
147 write!(f, "]")?;
148 Ok(())
149 }
150 }
151 }
152}
153
154pub fn display_decimal_128(num: i128, scale: u8) -> String {
155 let mut buf = String::new();
156 if scale == 0 {
157 write!(buf, "{num}").unwrap();
158 } else {
159 let pow_scale = 10_i128.pow(scale as u32);
160 if num >= 0 {
161 write!(
162 buf,
163 "{}.{:0>width$}",
164 num / pow_scale,
165 (num % pow_scale).abs(),
166 width = scale as usize
167 )
168 .unwrap();
169 } else {
170 write!(
171 buf,
172 "-{}.{:0>width$}",
173 -num / pow_scale,
174 (num % pow_scale).abs(),
175 width = scale as usize
176 )
177 .unwrap();
178 }
179 }
180 buf
181}
182
183pub fn display_decimal_256(num: i256, scale: u8) -> String {
184 let mut buf = String::new();
185 if scale == 0 {
186 write!(buf, "{}", num).unwrap();
187 } else {
188 let pow_scale = i256::from(10).pow(scale as u32);
189 if !num.is_negative() {
191 write!(
192 buf,
193 "{}.{:0>width$}",
194 num / pow_scale,
195 (num % pow_scale).wrapping_abs(),
196 width = scale as usize
197 )
198 } else {
199 write!(
200 buf,
201 "-{}.{:0>width$}",
202 -num / pow_scale,
203 (num % pow_scale).wrapping_abs(),
204 width = scale as usize
205 )
206 }
207 .expect("display_decimal_256 should not fail");
208 }
209 String::from_utf8_lossy(buf.as_bytes()).to_string()
210}