1use super::{NumberValue, Value, DAYS_FROM_CE, TIMESTAMP_FORMAT, TIMESTAMP_TIMEZONE_FORMAT};
16use crate::_macro_internal::Error;
17use crate::cursor_ext::{
18 collect_binary_number, collect_number, BufferReadStringExt, ReadBytesExt, ReadCheckPointExt,
19 ReadNumberExt,
20};
21use crate::error::{ConvertError, Result};
22use crate::value::base::GeoValue;
23use chrono::{Datelike, NaiveDate};
24use databend_client::schema::{DataType, DecimalDataType, DecimalSize, NumberDataType};
25use databend_client::ResultFormatSettings;
26use ethnum::i256;
27use hex;
28use jiff::{civil::DateTime as JiffDateTime, tz::TimeZone, Zoned};
29use serde::Deserialize;
30use serde_json::{value::RawValue, Deserializer};
31use std::io::{BufRead, Cursor};
32use std::str::FromStr;
33
34const NULL_VALUE: &str = "NULL";
35const TRUE_VALUE: &str = "1";
36const FALSE_VALUE: &str = "0";
37
38impl TryFrom<(&DataType, Option<String>, &ResultFormatSettings)> for Value {
39 type Error = Error;
40
41 fn try_from(
42 (t, v, settings): (&DataType, Option<String>, &ResultFormatSettings),
43 ) -> Result<Self> {
44 match v {
45 Some(v) => Self::try_from((t, v, settings)),
46 None => match t {
47 DataType::Null => Ok(Self::Null),
48 DataType::Nullable(_) => Ok(Self::Null),
49 _ => Err(Error::InvalidResponse(
50 "NULL value for non-nullable field".to_string(),
51 )),
52 },
53 }
54 }
55}
56
57impl TryFrom<(&DataType, String, &ResultFormatSettings)> for Value {
58 type Error = Error;
59
60 fn try_from((t, v, settings): (&DataType, String, &ResultFormatSettings)) -> Result<Self> {
61 match t {
62 DataType::Null => Ok(Self::Null),
63 DataType::EmptyArray => Ok(Self::EmptyArray),
64 DataType::EmptyMap => Ok(Self::EmptyMap),
65 DataType::Boolean => Ok(Self::Boolean(v == "1")),
66 DataType::Binary => Ok(Self::Binary(hex::decode(v)?)),
67 DataType::String => Ok(Self::String(v)),
68 DataType::Number(NumberDataType::Int8) => {
69 Ok(Self::Number(NumberValue::Int8(v.parse()?)))
70 }
71 DataType::Number(NumberDataType::Int16) => {
72 Ok(Self::Number(NumberValue::Int16(v.parse()?)))
73 }
74 DataType::Number(NumberDataType::Int32) => {
75 Ok(Self::Number(NumberValue::Int32(v.parse()?)))
76 }
77 DataType::Number(NumberDataType::Int64) => {
78 Ok(Self::Number(NumberValue::Int64(v.parse()?)))
79 }
80 DataType::Number(NumberDataType::UInt8) => {
81 Ok(Self::Number(NumberValue::UInt8(v.parse()?)))
82 }
83 DataType::Number(NumberDataType::UInt16) => {
84 Ok(Self::Number(NumberValue::UInt16(v.parse()?)))
85 }
86 DataType::Number(NumberDataType::UInt32) => {
87 Ok(Self::Number(NumberValue::UInt32(v.parse()?)))
88 }
89 DataType::Number(NumberDataType::UInt64) => {
90 Ok(Self::Number(NumberValue::UInt64(v.parse()?)))
91 }
92 DataType::Number(NumberDataType::Float32) => {
93 Ok(Self::Number(NumberValue::Float32(v.parse()?)))
94 }
95 DataType::Number(NumberDataType::Float64) => {
96 Ok(Self::Number(NumberValue::Float64(v.parse()?)))
97 }
98 DataType::Decimal(DecimalDataType::Decimal64(size)) => {
99 let d = parse_decimal(v.as_str(), *size)?;
100 Ok(Self::Number(d))
101 }
102 DataType::Decimal(DecimalDataType::Decimal128(size)) => {
103 let d = parse_decimal(v.as_str(), *size)?;
104 Ok(Self::Number(d))
105 }
106 DataType::Decimal(DecimalDataType::Decimal256(size)) => {
107 let d = parse_decimal(v.as_str(), *size)?;
108 Ok(Self::Number(d))
109 }
110 DataType::Timestamp => parse_timestamp(v.as_str(), &settings.timezone),
111 DataType::TimestampTz => {
112 let t = Zoned::strptime(TIMESTAMP_TIMEZONE_FORMAT, v.as_str())?;
113 Ok(Self::TimestampTz(t))
114 }
115 DataType::Date => Ok(Self::Date(
116 NaiveDate::parse_from_str(v.as_str(), "%Y-%m-%d")?.num_days_from_ce()
117 - DAYS_FROM_CE,
118 )),
119 DataType::Bitmap => Ok(Self::Bitmap(v)),
120 DataType::Variant => Ok(Self::Variant(v)),
121 DataType::Geometry => Ok(Self::Geometry(GeoValue::from_string(
122 v,
123 settings.geometry_output_format,
124 )?)),
125 DataType::Geography => Ok(Self::Geography(GeoValue::from_string(
126 v,
127 settings.geometry_output_format,
128 )?)),
129 DataType::Interval => Ok(Self::Interval(v)),
130 DataType::Array(_) | DataType::Map(_) | DataType::Tuple(_) | DataType::Vector(_) => {
131 let mut reader = Cursor::new(v.as_str());
132 let decoder = ValueDecoder {
133 settings: settings.clone(),
134 };
135 decoder.read_field(t, &mut reader)
136 }
137 DataType::Nullable(inner) => match inner.as_ref() {
138 DataType::String => Ok(Self::String(v.to_string())),
139 _ => {
140 if v == NULL_VALUE {
143 Ok(Self::Null)
144 } else {
145 Self::try_from((inner.as_ref(), v, settings))
146 }
147 }
148 },
149 }
150 }
151}
152
153struct ValueDecoder {
154 pub settings: ResultFormatSettings,
155}
156
157impl ValueDecoder {
158 pub(super) fn read_field<R: AsRef<[u8]>>(
159 &self,
160 ty: &DataType,
161 reader: &mut Cursor<R>,
162 ) -> Result<Value> {
163 match ty {
164 DataType::Null => self.read_null(reader),
165 DataType::EmptyArray => self.read_empty_array(reader),
166 DataType::EmptyMap => self.read_empty_map(reader),
167 DataType::Boolean => self.read_bool(reader),
168 DataType::Number(NumberDataType::Int8) => self.read_int8(reader),
169 DataType::Number(NumberDataType::Int16) => self.read_int16(reader),
170 DataType::Number(NumberDataType::Int32) => self.read_int32(reader),
171 DataType::Number(NumberDataType::Int64) => self.read_int64(reader),
172 DataType::Number(NumberDataType::UInt8) => self.read_uint8(reader),
173 DataType::Number(NumberDataType::UInt16) => self.read_uint16(reader),
174 DataType::Number(NumberDataType::UInt32) => self.read_uint32(reader),
175 DataType::Number(NumberDataType::UInt64) => self.read_uint64(reader),
176 DataType::Number(NumberDataType::Float32) => self.read_float32(reader),
177 DataType::Number(NumberDataType::Float64) => self.read_float64(reader),
178 DataType::Decimal(DecimalDataType::Decimal64(size)) => self.read_decimal(size, reader),
179 DataType::Decimal(DecimalDataType::Decimal128(size)) => self.read_decimal(size, reader),
180 DataType::Decimal(DecimalDataType::Decimal256(size)) => self.read_decimal(size, reader),
181 DataType::String => self.read_string(reader),
182 DataType::Binary => self.read_binary(reader),
183 DataType::Timestamp => self.read_timestamp(reader),
184 DataType::TimestampTz => self.read_timestamp_tz(reader),
185 DataType::Date => self.read_date(reader),
186 DataType::Bitmap => self.read_bitmap(reader),
187 DataType::Variant => self.read_variant(reader),
188 DataType::Geometry => self.read_geometry(reader),
189 DataType::Interval => self.read_interval(reader),
190 DataType::Geography => self.read_geography(reader),
191 DataType::Array(inner_ty) => self.read_array(inner_ty.as_ref(), reader),
192 DataType::Map(inner_ty) => self.read_map(inner_ty.as_ref(), reader),
193 DataType::Tuple(inner_tys) => self.read_tuple(inner_tys.as_ref(), reader),
194 DataType::Vector(dimension) => self.read_vector(*dimension as usize, reader),
195 DataType::Nullable(inner_ty) => self.read_nullable(inner_ty.as_ref(), reader),
196 }
197 }
198
199 fn match_bytes<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>, bs: &[u8]) -> bool {
200 let pos = reader.checkpoint();
201 if reader.ignore_bytes(bs) {
202 true
203 } else {
204 reader.rollback(pos);
205 false
206 }
207 }
208
209 fn read_null<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
210 if self.match_bytes(reader, NULL_VALUE.as_bytes()) {
211 Ok(Value::Null)
212 } else {
213 let buf = reader.fill_buf()?;
214 Err(ConvertError::new("null", String::from_utf8_lossy(buf).to_string()).into())
215 }
216 }
217
218 fn read_bool<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
219 if self.match_bytes(reader, TRUE_VALUE.as_bytes()) {
220 Ok(Value::Boolean(true))
221 } else if self.match_bytes(reader, FALSE_VALUE.as_bytes()) {
222 Ok(Value::Boolean(false))
223 } else {
224 let buf = reader.fill_buf()?;
225 Err(ConvertError::new("boolean", String::from_utf8_lossy(buf).to_string()).into())
226 }
227 }
228
229 fn read_int8<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
230 let v: i8 = reader.read_int_text()?;
231 Ok(Value::Number(NumberValue::Int8(v)))
232 }
233
234 fn read_int16<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
235 let v: i16 = reader.read_int_text()?;
236 Ok(Value::Number(NumberValue::Int16(v)))
237 }
238
239 fn read_int32<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
240 let v: i32 = reader.read_int_text()?;
241 Ok(Value::Number(NumberValue::Int32(v)))
242 }
243
244 fn read_int64<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
245 let v: i64 = reader.read_int_text()?;
246 Ok(Value::Number(NumberValue::Int64(v)))
247 }
248
249 fn read_uint8<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
250 let v: u8 = reader.read_int_text()?;
251 Ok(Value::Number(NumberValue::UInt8(v)))
252 }
253
254 fn read_uint16<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
255 let v: u16 = reader.read_int_text()?;
256 Ok(Value::Number(NumberValue::UInt16(v)))
257 }
258
259 fn read_uint32<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
260 let v: u32 = reader.read_int_text()?;
261 Ok(Value::Number(NumberValue::UInt32(v)))
262 }
263
264 fn read_uint64<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
265 let v: u64 = reader.read_int_text()?;
266 Ok(Value::Number(NumberValue::UInt64(v)))
267 }
268
269 fn read_float32<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
270 let v: f32 = reader.read_float_text()?;
271 Ok(Value::Number(NumberValue::Float32(v)))
272 }
273
274 fn read_float64<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
275 let v: f64 = reader.read_float_text()?;
276 Ok(Value::Number(NumberValue::Float64(v)))
277 }
278
279 fn read_decimal<R: AsRef<[u8]>>(
280 &self,
281 size: &DecimalSize,
282 reader: &mut Cursor<R>,
283 ) -> Result<Value> {
284 let buf = reader.fill_buf()?;
285 let (n_in, _) = collect_number(buf);
288 let v = unsafe { std::str::from_utf8_unchecked(&buf[..n_in]) };
289 let d = parse_decimal(v, *size)?;
290 reader.consume(n_in);
291 Ok(Value::Number(d))
292 }
293
294 fn read_string<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
295 let mut buf = Vec::new();
296 if reader.read_quoted_text(&mut buf, b'"').is_err() {
297 reader.read_quoted_text(&mut buf, b'\'')?;
298 }
299 Ok(Value::String(unsafe { String::from_utf8_unchecked(buf) }))
300 }
301
302 fn read_binary<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
303 let buf = reader.fill_buf()?;
304 let n = collect_binary_number(buf);
305 let v = buf[..n].to_vec();
306 reader.consume(n);
307 Ok(Value::Binary(hex::decode(v)?))
308 }
309
310 fn read_date<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
311 let mut buf = Vec::new();
312 if reader.read_quoted_text(&mut buf, b'"').is_err() {
313 reader.read_quoted_text(&mut buf, b'\'')?;
314 }
315 let v = unsafe { std::str::from_utf8_unchecked(&buf) };
316 let days = NaiveDate::parse_from_str(v, "%Y-%m-%d")?.num_days_from_ce() - DAYS_FROM_CE;
317 Ok(Value::Date(days))
318 }
319
320 fn read_timestamp<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
321 let mut buf = Vec::new();
322 if reader.read_quoted_text(&mut buf, b'"').is_err() {
323 reader.read_quoted_text(&mut buf, b'\'')?;
324 }
325 let v = unsafe { std::str::from_utf8_unchecked(&buf) };
326 parse_timestamp(v, &self.settings.timezone)
327 }
328
329 fn read_timestamp_tz<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
330 let mut buf = Vec::new();
331 if reader.read_quoted_text(&mut buf, b'"').is_err() {
332 reader.read_quoted_text(&mut buf, b'\'')?;
333 }
334 let v = unsafe { std::str::from_utf8_unchecked(&buf) };
335 let t = Zoned::strptime(TIMESTAMP_TIMEZONE_FORMAT, v)?;
336 Ok(Value::TimestampTz(t))
337 }
338
339 fn read_interval<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
340 let mut buf = Vec::new();
341 if reader.read_quoted_text(&mut buf, b'"').is_err() {
342 reader.read_quoted_text(&mut buf, b'\'')?;
343 }
344 Ok(Value::Interval(unsafe { String::from_utf8_unchecked(buf) }))
345 }
346
347 fn read_bitmap<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
348 let mut buf = Vec::new();
349 if reader.read_quoted_text(&mut buf, b'"').is_err() {
350 reader.read_quoted_text(&mut buf, b'\'')?;
351 }
352 Ok(Value::Bitmap(unsafe { String::from_utf8_unchecked(buf) }))
353 }
354
355 fn read_variant<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
356 if let Ok(val) = self.read_json(reader) {
357 Ok(Value::Variant(val))
358 } else {
359 let mut buf = Vec::new();
360 reader.read_quoted_text(&mut buf, b'\'')?;
361 Ok(Value::Variant(unsafe { String::from_utf8_unchecked(buf) }))
362 }
363 }
364
365 fn read_geometry<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
366 Ok(Value::Geometry(self.read_geo(reader)?))
367 }
368
369 fn read_geo<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<GeoValue> {
370 let mut buf = Vec::new();
371 if reader.read_quoted_text(&mut buf, b'"').is_ok()
372 || reader.read_quoted_text(&mut buf, b'\'').is_ok()
373 {
374 let s = unsafe { String::from_utf8_unchecked(buf) };
375 GeoValue::from_string(s, self.settings.geometry_output_format)
376 } else {
377 let val = self.read_json(reader)?;
378 Ok(GeoValue::String(val))
379 }
380 }
381 fn read_geography<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
382 Ok(Value::Geography(self.read_geo(reader)?))
383 }
384
385 fn read_nullable<R: AsRef<[u8]>>(
386 &self,
387 ty: &DataType,
388 reader: &mut Cursor<R>,
389 ) -> Result<Value> {
390 match self.read_null(reader) {
391 Ok(val) => Ok(val),
392 Err(_) => self.read_field(ty, reader),
393 }
394 }
395
396 fn read_empty_array<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
397 reader.must_ignore_byte(b'[')?;
398 reader.must_ignore_byte(b']')?;
399 Ok(Value::EmptyArray)
400 }
401
402 fn read_empty_map<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<Value> {
403 reader.must_ignore_byte(b'{')?;
404 reader.must_ignore_byte(b'}')?;
405 Ok(Value::EmptyArray)
406 }
407
408 fn read_array<R: AsRef<[u8]>>(&self, ty: &DataType, reader: &mut Cursor<R>) -> Result<Value> {
409 let mut vals = Vec::new();
410 reader.must_ignore_byte(b'[')?;
411 for idx in 0.. {
412 let _ = reader.ignore_white_spaces();
413 if reader.ignore_byte(b']') {
414 break;
415 }
416 if idx != 0 {
417 reader.must_ignore_byte(b',')?;
418 }
419 let _ = reader.ignore_white_spaces();
420 let val = self.read_field(ty, reader)?;
421 vals.push(val);
422 }
423 Ok(Value::Array(vals))
424 }
425
426 fn read_vector<R: AsRef<[u8]>>(
427 &self,
428 dimension: usize,
429 reader: &mut Cursor<R>,
430 ) -> Result<Value> {
431 let mut vals = Vec::with_capacity(dimension);
432 reader.must_ignore_byte(b'[')?;
433 for idx in 0..dimension {
434 let _ = reader.ignore_white_spaces();
435 if idx > 0 {
436 reader.must_ignore_byte(b',')?;
437 }
438 let _ = reader.ignore_white_spaces();
439 let val: f32 = reader.read_float_text()?;
440 vals.push(val);
441 }
442 reader.must_ignore_byte(b']')?;
443 Ok(Value::Vector(vals))
444 }
445
446 fn read_map<R: AsRef<[u8]>>(&self, ty: &DataType, reader: &mut Cursor<R>) -> Result<Value> {
447 const KEY: usize = 0;
448 const VALUE: usize = 1;
449 let mut kvs = Vec::new();
450 reader.must_ignore_byte(b'{')?;
451 match ty {
452 DataType::Tuple(inner_tys) => {
453 for idx in 0.. {
454 let _ = reader.ignore_white_spaces();
455 if reader.ignore_byte(b'}') {
456 break;
457 }
458 if idx != 0 {
459 reader.must_ignore_byte(b',')?;
460 }
461 let _ = reader.ignore_white_spaces();
462 let key = self.read_field(&inner_tys[KEY], reader)?;
463 let _ = reader.ignore_white_spaces();
464 reader.must_ignore_byte(b':')?;
465 let _ = reader.ignore_white_spaces();
466 let val = self.read_field(&inner_tys[VALUE], reader)?;
467 kvs.push((key, val));
468 }
469 Ok(Value::Map(kvs))
470 }
471 _ => unreachable!(),
472 }
473 }
474
475 fn read_tuple<R: AsRef<[u8]>>(
476 &self,
477 tys: &[DataType],
478 reader: &mut Cursor<R>,
479 ) -> Result<Value> {
480 let mut vals = Vec::new();
481 reader.must_ignore_byte(b'(')?;
482 for (idx, ty) in tys.iter().enumerate() {
483 let _ = reader.ignore_white_spaces();
484 if idx != 0 {
485 reader.must_ignore_byte(b',')?;
486 }
487 let _ = reader.ignore_white_spaces();
488 let val = self.read_field(ty, reader)?;
489 vals.push(val);
490 }
491 reader.must_ignore_byte(b')')?;
492 Ok(Value::Tuple(vals))
493 }
494
495 fn read_json<R: AsRef<[u8]>>(&self, reader: &mut Cursor<R>) -> Result<String> {
496 let start = reader.position() as usize;
497 let data = reader.get_ref().as_ref();
498 let mut deserializer = Deserializer::from_slice(&data[start..]);
499 let raw: Box<RawValue> = Box::<RawValue>::deserialize(&mut deserializer)?;
500 reader.set_position((start + raw.get().len()) as u64);
501 Ok(raw.to_string())
502 }
503}
504
505fn parse_timestamp(ts_string: &str, tz: &TimeZone) -> Result<Value> {
506 let local = JiffDateTime::strptime(TIMESTAMP_FORMAT, ts_string)?;
507 let dt_with_tz = local.to_zoned(tz.clone()).map_err(|e| {
508 Error::Parsing(format!(
509 "time {ts_string} not exists in timezone {tz:?}: {e}"
510 ))
511 })?;
512 Ok(Value::Timestamp(dt_with_tz))
513}
514
515fn parse_decimal(text: &str, size: DecimalSize) -> Result<NumberValue> {
516 let mut start = 0;
517 let bytes = text.as_bytes();
518 let mut is_negative = false;
519
520 if bytes[start] == b'-' {
522 is_negative = true;
523 start += 1;
524 }
525
526 while start < text.len() && bytes[start] == b'0' {
527 start += 1
528 }
529 let text = &text[start..];
530 let point_pos = text.find('.');
531 let e_pos = text.find(|c| ['E', 'e'].contains(&c));
532 let (i_part, f_part, e_part) = match (point_pos, e_pos) {
533 (Some(p1), Some(p2)) => (&text[..p1], &text[(p1 + 1)..p2], Some(&text[(p2 + 1)..])),
534 (Some(p), None) => (&text[..p], &text[(p + 1)..], None),
535 (None, Some(p)) => (&text[..p], "", Some(&text[(p + 1)..])),
536 (None, None) => (text, "", None),
537 };
538 let exp = match e_part {
539 Some(s) => s.parse::<i32>()?,
540 None => 0,
541 };
542 if i_part.len() as i32 + exp > 76 {
543 Err(ConvertError::new("decimal", format!("{text:?}")).into())
544 } else {
545 let mut digits = Vec::with_capacity(76);
546 digits.extend_from_slice(i_part.as_bytes());
547 digits.extend_from_slice(f_part.as_bytes());
548 if digits.is_empty() {
549 digits.push(b'0')
550 }
551 let scale = f_part.len() as i32 - exp;
552 if scale < 0 {
553 for _ in 0..(-scale) {
555 digits.push(b'0')
556 }
557 };
558
559 let precision = std::cmp::min(digits.len(), 76);
560 let digits = unsafe { std::str::from_utf8_unchecked(&digits[..precision]) };
561
562 let result = if size.precision > 38 {
563 NumberValue::Decimal256(i256::from_str(digits).unwrap(), size)
564 } else if size.precision > 19 {
565 NumberValue::Decimal128(digits.parse::<i128>()?, size)
566 } else {
567 NumberValue::Decimal64(digits.parse::<i64>()?, size)
568 };
569
570 if is_negative {
572 match result {
573 NumberValue::Decimal256(val, size) => Ok(NumberValue::Decimal256(-val, size)),
574 NumberValue::Decimal128(val, size) => Ok(NumberValue::Decimal128(-val, size)),
575 NumberValue::Decimal64(val, size) => Ok(NumberValue::Decimal64(-val, size)),
576 _ => Ok(result),
577 }
578 } else {
579 Ok(result)
580 }
581 }
582}