JsonlValueDeserialize

Trait JsonlValueDeserialize 

Source
pub trait JsonlValueDeserialize {
    // Required method
    fn deserialize_values(self) -> impl Stream<Item = Result<Value>>;
}
Expand description

Extension trait specifically for deserializing JSONL to serde_json::Value objects.

This trait provides a convenient method to deserialize JSON lines into generic serde_json::Value objects when you don’t know the exact structure of the JSON data ahead of time or when working with heterogeneous JSON objects.

§Examples

§Basic Usage with Dynamic JSON

use async_jsonl::{Jsonl, JsonlValueDeserialize};
use futures::StreamExt;
use std::io::Cursor;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let data = r#"{"user_id": 123, "action": "login", "timestamp": "2024-01-01T10:00:00Z"}
{"user_id": 456, "action": "logout", "timestamp": "2024-01-01T11:00:00Z"}
{"user_id": 789, "action": "purchase", "item": "widget", "price": 29.99}"#;
     
    let reader = Jsonl::new(Cursor::new(data.as_bytes()));
    let mut value_stream = reader.deserialize_values();
     
    while let Some(result) = value_stream.next().await {
        match result {
            Ok(value) => {
                println!("Event: {}", value["action"]);
                if let Some(price) = value.get("price") {
                    println!("  Purchase amount: {}", price);
                }
            }
            Err(e) => eprintln!("Failed to parse JSON: {}", e),
        }
    }
     
    Ok(())
}

§Processing Mixed JSON Structures

use async_jsonl::{Jsonl, JsonlValueDeserialize};
use futures::StreamExt;
use serde_json::Value;
use std::io::Cursor;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let mixed_data = r#"{"type": "user", "name": "Alice", "age": 30}
{"type": "product", "name": "Widget", "price": 19.99, "categories": ["tools", "hardware"]}
{"type": "event", "name": "click", "target": "button", "metadata": {"page": "/home"}}"#;
     
    let reader = Jsonl::new(Cursor::new(mixed_data.as_bytes()));
    let values: Vec<Value> = reader
        .deserialize_values()
        .collect::<Vec<_>>()
        .await
        .into_iter()
        .collect::<Result<Vec<_>, _>>()?;
     
    for value in values {
        match value["type"].as_str() {
            Some("user") => println!("User: {} (age {})", value["name"], value["age"]),
            Some("product") => println!("Product: {} - ${}", value["name"], value["price"]),
            Some("event") => println!("Event: {} on {}", value["name"], value["target"]),
            _ => println!("Unknown type: {:?}", value),
        }
    }
     
    Ok(())
}

§Error Handling with Invalid JSON

use async_jsonl::{Jsonl, JsonlValueDeserialize};
use futures::StreamExt;
use std::io::Cursor;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let data_with_errors = r#"{"valid": "json"}
{invalid json line
{"another": "valid line"}"#;
     
    let reader = Jsonl::new(Cursor::new(data_with_errors.as_bytes()));
    let mut value_stream = reader.deserialize_values();
     
    let mut valid_count = 0;
    let mut error_count = 0;
     
    while let Some(result) = value_stream.next().await {
        match result {
            Ok(_) => valid_count += 1,
            Err(_) => error_count += 1,
        }
    }
     
    println!("Valid JSON lines: {}, Errors: {}", valid_count, error_count);
    Ok(())
}

Required Methods§

Source

fn deserialize_values(self) -> impl Stream<Item = Result<Value>>

Deserialize JSON lines into serde_json::Value objects.

This method transforms each line of a JSONL stream into serde_json::Value objects, which can represent any valid JSON structure. This is useful when:

  • You don’t know the exact structure of the JSON data ahead of time
  • You’re working with heterogeneous JSON objects in the same file
  • You want to inspect or transform JSON data dynamically
  • You need to handle mixed or evolving JSON schemas
§Returns

Returns a Stream of anyhow::Result<Value> where:

  • Ok(Value) represents a successfully parsed JSON value
  • Err(anyhow::Error) represents parsing errors for invalid JSON lines
§Examples
use async_jsonl::{Jsonl, JsonlValueDeserialize};
use futures::StreamExt;
use std::io::Cursor;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let data = r#"{"id": 1, "data": {"nested": [1, 2, 3]}}
{"id": 2, "data": {"different": "structure"}}"#;
     
    let reader = Jsonl::new(Cursor::new(data.as_bytes()));
    let values: Vec<_> = reader
        .deserialize_values()
        .collect()
        .await;
     
    for (i, result) in values.iter().enumerate() {
        match result {
            Ok(value) => println!("Object {}: ID = {}", i + 1, value["id"]),
            Err(e) => eprintln!("Error parsing object {}: {}", i + 1, e),
        }
    }
     
    Ok(())
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§