|
18 | 18 | //! Module for converting Variant data to JSON format |
19 | 19 |
|
20 | 20 | use arrow_schema::ArrowError; |
| 21 | +use base64::{Engine as _, engine::general_purpose}; |
21 | 22 | use serde_json::Value; |
22 | 23 | use std::io::Write; |
23 | 24 |
|
@@ -67,6 +68,55 @@ pub fn variant_to_json<W: Write>( |
67 | 68 | Variant::Int8(i) => { |
68 | 69 | write!(json_buffer, "{}", i)?; |
69 | 70 | } |
| 71 | + Variant::Int16(i) => { |
| 72 | + write!(json_buffer, "{}", i)?; |
| 73 | + } |
| 74 | + Variant::Int32(i) => { |
| 75 | + write!(json_buffer, "{}", i)?; |
| 76 | + } |
| 77 | + Variant::Int64(i) => { |
| 78 | + write!(json_buffer, "{}", i)?; |
| 79 | + } |
| 80 | + Variant::Float(f) => { |
| 81 | + write!(json_buffer, "{}", f)?; |
| 82 | + } |
| 83 | + Variant::Double(f) => { |
| 84 | + write!(json_buffer, "{}", f)?; |
| 85 | + } |
| 86 | + Variant::Decimal4 { integer, scale } => { |
| 87 | + // Convert decimal to string representation |
| 88 | + let divisor = 10_i32.pow(*scale as u32); |
| 89 | + let decimal_value = *integer as f64 / divisor as f64; |
| 90 | + write!(json_buffer, "{}", decimal_value)?; |
| 91 | + } |
| 92 | + Variant::Decimal8 { integer, scale } => { |
| 93 | + // Convert decimal to string representation |
| 94 | + let divisor = 10_i64.pow(*scale as u32); |
| 95 | + let decimal_value = *integer as f64 / divisor as f64; |
| 96 | + write!(json_buffer, "{}", decimal_value)?; |
| 97 | + } |
| 98 | + Variant::Decimal16 { integer, scale } => { |
| 99 | + // Convert decimal to string representation |
| 100 | + let divisor = 10_i128.pow(*scale as u32); |
| 101 | + let decimal_value = *integer as f64 / divisor as f64; |
| 102 | + write!(json_buffer, "{}", decimal_value)?; |
| 103 | + } |
| 104 | + Variant::Date(date) => { |
| 105 | + write!(json_buffer, "\"{}\"", date.format("%Y-%m-%d"))?; |
| 106 | + } |
| 107 | + Variant::TimestampMicros(ts) => { |
| 108 | + write!(json_buffer, "\"{}\"", ts.to_rfc3339())?; |
| 109 | + } |
| 110 | + Variant::TimestampNtzMicros(ts) => { |
| 111 | + write!(json_buffer, "\"{}\"", ts.format("%Y-%m-%dT%H:%M:%S%.6f"))?; |
| 112 | + } |
| 113 | + Variant::Binary(bytes) => { |
| 114 | + // Encode binary as base64 string |
| 115 | + let base64_str = general_purpose::STANDARD.encode(bytes); |
| 116 | + let json_str = serde_json::to_string(&base64_str) |
| 117 | + .map_err(|e| ArrowError::InvalidArgumentError(format!("JSON encoding error: {}", e)))?; |
| 118 | + write!(json_buffer, "{}", json_str)?; |
| 119 | + } |
70 | 120 | Variant::String(s) | Variant::ShortString(s) => { |
71 | 121 | // Use serde_json to properly escape the string |
72 | 122 | let json_str = serde_json::to_string(s) |
@@ -198,6 +248,44 @@ pub fn variant_to_json_value(variant: &Variant) -> Result<Value, ArrowError> { |
198 | 248 | Variant::BooleanTrue => Ok(Value::Bool(true)), |
199 | 249 | Variant::BooleanFalse => Ok(Value::Bool(false)), |
200 | 250 | Variant::Int8(i) => Ok(Value::Number((*i).into())), |
| 251 | + Variant::Int16(i) => Ok(Value::Number((*i).into())), |
| 252 | + Variant::Int32(i) => Ok(Value::Number((*i).into())), |
| 253 | + Variant::Int64(i) => Ok(Value::Number((*i).into())), |
| 254 | + Variant::Float(f) => { |
| 255 | + serde_json::Number::from_f64(*f as f64) |
| 256 | + .map(Value::Number) |
| 257 | + .ok_or_else(|| ArrowError::InvalidArgumentError("Invalid float value".to_string())) |
| 258 | + } |
| 259 | + Variant::Double(f) => { |
| 260 | + serde_json::Number::from_f64(*f) |
| 261 | + .map(Value::Number) |
| 262 | + .ok_or_else(|| ArrowError::InvalidArgumentError("Invalid double value".to_string())) |
| 263 | + } |
| 264 | + Variant::Decimal4 { integer, scale } => { |
| 265 | + let divisor = 10_i32.pow(*scale as u32); |
| 266 | + let decimal_value = *integer as f64 / divisor as f64; |
| 267 | + serde_json::Number::from_f64(decimal_value) |
| 268 | + .map(Value::Number) |
| 269 | + .ok_or_else(|| ArrowError::InvalidArgumentError("Invalid decimal value".to_string())) |
| 270 | + } |
| 271 | + Variant::Decimal8 { integer, scale } => { |
| 272 | + let divisor = 10_i64.pow(*scale as u32); |
| 273 | + let decimal_value = *integer as f64 / divisor as f64; |
| 274 | + serde_json::Number::from_f64(decimal_value) |
| 275 | + .map(Value::Number) |
| 276 | + .ok_or_else(|| ArrowError::InvalidArgumentError("Invalid decimal value".to_string())) |
| 277 | + } |
| 278 | + Variant::Decimal16 { integer, scale } => { |
| 279 | + let divisor = 10_i128.pow(*scale as u32); |
| 280 | + let decimal_value = *integer as f64 / divisor as f64; |
| 281 | + serde_json::Number::from_f64(decimal_value) |
| 282 | + .map(Value::Number) |
| 283 | + .ok_or_else(|| ArrowError::InvalidArgumentError("Invalid decimal value".to_string())) |
| 284 | + } |
| 285 | + Variant::Date(date) => Ok(Value::String(date.format("%Y-%m-%d").to_string())), |
| 286 | + Variant::TimestampMicros(ts) => Ok(Value::String(ts.to_rfc3339())), |
| 287 | + Variant::TimestampNtzMicros(ts) => Ok(Value::String(ts.format("%Y-%m-%dT%H:%M:%S%.6f").to_string())), |
| 288 | + Variant::Binary(bytes) => Ok(Value::String(general_purpose::STANDARD.encode(bytes))), |
201 | 289 | Variant::String(s) | Variant::ShortString(s) => Ok(Value::String(s.to_string())), |
202 | 290 | Variant::Object(obj) => { |
203 | 291 | let mut map = serde_json::Map::new(); |
|
0 commit comments