This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 72e91fcb3f [Variant] Consolidate examples for json writing (#7782)
72e91fcb3f is described below
commit 72e91fcb3f6b8e92a3694e7e2e8a04eaaf161a96
Author: Andrew Lamb <[email protected]>
AuthorDate: Thu Jun 26 16:10:40 2025 -0400
[Variant] Consolidate examples for json writing (#7782)
# Which issue does this PR close?
We generally require a GitHub issue to be filed for all bug fixes and
enhancements and this helps us generate change logs for our releases.
You can link an issue to this PR using the GitHub syntax.
- Follow on to https://github.com/apache/arrow-rs/pull/7670 from
@carpecodeum
- Part of https://github.com/apache/arrow-rs/issues/6736
# Rationale for this change
I was going through the code and examples and I felt that there was some
redundancy and that the example file was unlikely to be found as not
many crates in this repo have examples
I would like to propose moving the examples as close to the actual code
as possible to give it the best chance to be discovered.
# What changes are included in this PR?
1. Remove `parquet-variant/examples/variant_to_json_examples.rs`
2. Update some of the other examples and docs for the json functions
with content from that example
# Are these changes tested?
The examples are covered by CI tests.
# Are there any user-facing changes?
Different docs
---
.../examples/variant_to_json_examples.rs | 55 ----------------
parquet-variant/src/to_json.rs | 77 ++++++++++------------
2 files changed, 35 insertions(+), 97 deletions(-)
diff --git a/parquet-variant/examples/variant_to_json_examples.rs
b/parquet-variant/examples/variant_to_json_examples.rs
deleted file mode 100644
index 30e066ba3a..0000000000
--- a/parquet-variant/examples/variant_to_json_examples.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-//! Example showing how to convert Variant values to JSON
-
-use parquet_variant::{
- variant_to_json, variant_to_json_string, variant_to_json_value,
VariantBuilder,
-};
-
-fn main() -> Result<(), Box<dyn std::error::Error>> {
- let mut builder = VariantBuilder::new();
-
- {
- let mut person = builder.new_object();
- person.insert("name", "Alice");
- person.insert("age", 30i32);
- person.insert("email", "[email protected]");
- person.insert("is_active", true);
- person.insert("score", 95.7f64);
- person.insert("department", "Engineering");
- person.finish();
- }
-
- let (metadata, value) = builder.finish();
- let variant = parquet_variant::Variant::try_new(&metadata, &value)?;
-
- let json_string = variant_to_json_string(&variant)?;
- let json_value = variant_to_json_value(&variant)?;
- let pretty_json = serde_json::to_string_pretty(&json_value)?;
- println!("{}", pretty_json);
-
- let mut buffer = Vec::new();
- variant_to_json(&mut buffer, &variant)?;
- let buffer_result = String::from_utf8(buffer)?;
-
- // Verify all methods produce the same result
- assert_eq!(json_string, buffer_result);
- assert_eq!(json_string, serde_json::to_string(&json_value)?);
-
- Ok(())
-}
diff --git a/parquet-variant/src/to_json.rs b/parquet-variant/src/to_json.rs
index 51f18c4aac..9e5cbdccef 100644
--- a/parquet-variant/src/to_json.rs
+++ b/parquet-variant/src/to_json.rs
@@ -16,7 +16,6 @@
// under the License.
//! Module for converting Variant data to JSON format
-
use arrow_schema::ArrowError;
use base64::{engine::general_purpose, Engine as _};
use serde_json::Value;
@@ -86,14 +85,17 @@ fn write_decimal_i64(
Ok(())
}
-/// Converts a Variant to JSON and writes it to the provided `Write`
+/// Converts a Variant to JSON and writes it to the provided [`Write`]
///
/// This function writes JSON directly to any type that implements [`Write`],
/// making it efficient for streaming or when you want to control the output
destination.
///
+/// See [`variant_to_json_string`] for a convenience function that returns a
+/// JSON string.
+///
/// # Arguments
///
-/// * `json_buffer` - Writer to output JSON to
+/// * `writer` - Writer to output JSON to
/// * `variant` - The Variant value to convert
///
/// # Returns
@@ -103,23 +105,34 @@ fn write_decimal_i64(
///
/// # Examples
///
+///
/// ```rust
/// # use parquet_variant::{Variant, variant_to_json};
/// # use arrow_schema::ArrowError;
-/// let variant = Variant::Int32(42);
+/// let variant = Variant::from("Hello, World!");
/// let mut buffer = Vec::new();
/// variant_to_json(&mut buffer, &variant)?;
-/// assert_eq!(String::from_utf8(buffer).unwrap(), "42");
+/// assert_eq!(String::from_utf8(buffer).unwrap(), "\"Hello, World!\"");
/// # Ok::<(), ArrowError>(())
/// ```
///
+/// # Example: Create a [`Variant::Object`] and convert to JSON
/// ```rust
-/// # use parquet_variant::{Variant, variant_to_json};
+/// # use parquet_variant::{Variant, VariantBuilder, variant_to_json};
/// # use arrow_schema::ArrowError;
-/// let variant = Variant::String("Hello, World!");
-/// let mut buffer = Vec::new();
-/// variant_to_json(&mut buffer, &variant)?;
-/// assert_eq!(String::from_utf8(buffer).unwrap(), "\"Hello, World!\"");
+/// let mut builder = VariantBuilder::new();
+/// // Create an object builder that will write fields to the object
+/// let mut object_builder = builder.new_object();
+/// object_builder.insert("first_name", "Jiaying");
+/// object_builder.insert("last_name", "Li");
+/// object_builder.finish();
+/// // Finish the builder to get the metadata and value
+/// let (metadata, value) = builder.finish();
+/// // Create the Variant and convert to JSON
+/// let variant = Variant::try_new(&metadata, &value)?;
+/// let mut writer = Vec::new();
+/// variant_to_json(&mut writer, &variant,)?;
+/// assert_eq!(br#"{"first_name":"Jiaying","last_name":"Li"}"#,
writer.as_slice());
/// # Ok::<(), ArrowError>(())
/// ```
pub fn variant_to_json(json_buffer: &mut impl Write, variant: &Variant) ->
Result<(), ArrowError> {
@@ -243,10 +256,10 @@ fn convert_array_to_json(buffer: &mut impl Write, arr:
&VariantList) -> Result<(
Ok(())
}
-/// Convert Variant to JSON string
+/// Convert [`Variant`] to JSON [`String`]
///
/// This is a convenience function that converts a Variant to a JSON string.
-/// This is the same as calling variant_to_json with a Vec
+/// This is the same as calling [`variant_to_json`] with a [`Vec`].
/// It's the simplest way to get a JSON representation when you just need a
String result.
///
/// # Arguments
@@ -269,15 +282,6 @@ fn convert_array_to_json(buffer: &mut impl Write, arr:
&VariantList) -> Result<(
/// # Ok::<(), ArrowError>(())
/// ```
///
-/// ```rust
-/// # use parquet_variant::{Variant, variant_to_json_string};
-/// # use arrow_schema::ArrowError;
-/// let variant = Variant::String("Hello, World!");
-/// let json = variant_to_json_string(&variant)?;
-/// assert_eq!(json, "\"Hello, World!\"");
-/// # Ok::<(), ArrowError>(())
-/// ```
-///
/// # Example: Create a [`Variant::Object`] and convert to JSON
///
/// This example shows how to create an object with two fields and convert it
to JSON:
@@ -302,8 +306,7 @@ fn convert_array_to_json(buffer: &mut impl Write, arr:
&VariantList) -> Result<(
/// // Create the Variant and convert to JSON
/// let variant = Variant::try_new(&metadata, &value)?;
/// let json = variant_to_json_string(&variant)?;
-/// assert!(json.contains("\"first_name\":\"Jiaying\""));
-/// assert!(json.contains("\"last_name\":\"Li\""));
+/// assert_eq!(r#"{"first_name":"Jiaying","last_name":"Li"}"#, json);
/// # Ok::<(), ArrowError>(())
/// ```
pub fn variant_to_json_string(variant: &Variant) -> Result<String, ArrowError>
{
@@ -313,7 +316,7 @@ pub fn variant_to_json_string(variant: &Variant) ->
Result<String, ArrowError> {
.map_err(|e| ArrowError::InvalidArgumentError(format!("UTF-8
conversion error: {}", e)))
}
-/// Convert Variant to serde_json::Value
+/// Convert [`Variant`] to [`serde_json::Value`]
///
/// This function converts a Variant to a [`serde_json::Value`], which is
useful
/// when you need to work with the JSON data programmatically or integrate with
@@ -334,17 +337,7 @@ pub fn variant_to_json_string(variant: &Variant) ->
Result<String, ArrowError> {
/// # use parquet_variant::{Variant, variant_to_json_value};
/// # use serde_json::Value;
/// # use arrow_schema::ArrowError;
-/// let variant = Variant::Int32(42);
-/// let json_value = variant_to_json_value(&variant)?;
-/// assert_eq!(json_value, Value::Number(42.into()));
-/// # Ok::<(), ArrowError>(())
-/// ```
-///
-/// ```rust
-/// # use parquet_variant::{Variant, variant_to_json_value};
-/// # use serde_json::Value;
-/// # use arrow_schema::ArrowError;
-/// let variant = Variant::String("hello");
+/// let variant = Variant::from("hello");
/// let json_value = variant_to_json_value(&variant)?;
/// assert_eq!(json_value, Value::String("hello".to_string()));
/// # Ok::<(), ArrowError>(())
@@ -547,7 +540,7 @@ mod tests {
#[test]
fn test_string_to_json() -> Result<(), ArrowError> {
- let variant = Variant::String("hello world");
+ let variant = Variant::from("hello world");
let json = variant_to_json_string(&variant)?;
assert_eq!(json, "\"hello world\"");
@@ -571,7 +564,7 @@ mod tests {
#[test]
fn test_string_escaping() -> Result<(), ArrowError> {
- let variant = Variant::String("hello\nworld\t\"quoted\"");
+ let variant = Variant::from("hello\nworld\t\"quoted\"");
let json = variant_to_json_string(&variant)?;
assert_eq!(json, "\"hello\\nworld\\t\\\"quoted\\\"\"");
@@ -822,14 +815,14 @@ mod tests {
// Strings
JsonTest {
- variant: Variant::String("hello world"),
+ variant: Variant::from("hello world"),
expected_json: "\"hello world\"",
expected_value: Value::String("hello world".to_string()),
}
.run();
JsonTest {
- variant: Variant::String(""),
+ variant: Variant::from(""),
expected_json: "\"\"",
expected_value: Value::String("".to_string()),
}
@@ -877,14 +870,14 @@ mod tests {
fn test_string_escaping_comprehensive() {
// Test comprehensive string escaping scenarios
JsonTest {
- variant: Variant::String("line1\nline2\ttab\"quote\"\\backslash"),
+ variant: Variant::from("line1\nline2\ttab\"quote\"\\backslash"),
expected_json: "\"line1\\nline2\\ttab\\\"quote\\\"\\\\backslash\"",
expected_value:
Value::String("line1\nline2\ttab\"quote\"\\backslash".to_string()),
}
.run();
JsonTest {
- variant: Variant::String("Hello δΈη π"),
+ variant: Variant::from("Hello δΈη π"),
expected_json: "\"Hello δΈη π\"",
expected_value: Value::String("Hello δΈη π".to_string()),
}
@@ -895,7 +888,7 @@ mod tests {
fn test_buffer_writing_variants() -> Result<(), ArrowError> {
use crate::variant_to_json;
- let variant = Variant::String("test buffer writing");
+ let variant = Variant::from("test buffer writing");
// Test writing to a Vec<u8>
let mut buffer = Vec::new();