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