use serde::{Deserialize, Serialize};
use turboclaude_core::serde::SerializePipeline;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct Message {
role: Role,
content: String,
#[serde(skip_serializing_if = "Option::is_none")]
metadata: Option<Metadata>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
enum Role {
User,
Assistant,
System,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct Metadata {
timestamp: u64,
tokens: u32,
#[serde(default)]
tags: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct Config {
api_key: String,
model: String,
max_tokens: u32,
temperature: f32,
#[serde(default)]
stop_sequences: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct Conversation {
id: String,
messages: Vec<Message>,
config: Config,
#[serde(skip_serializing_if = "Option::is_none")]
summary: Option<String>,
}
fn main() {
println!("=== TurboClaude Core: Serialization Pipeline Examples ===\n");
println!("Example 1: Simple message serialization");
let msg = Message {
role: Role::User,
content: "Hello, Claude!".to_string(),
metadata: None,
};
let json_str = msg.to_json_string().unwrap();
println!(" Compact JSON: {}", json_str);
let pretty = msg.to_json_string_pretty().unwrap();
println!(" Pretty JSON:\n{}", indent(&pretty, 4));
println!();
println!("Example 2: Message with metadata");
let msg_with_meta = Message {
role: Role::Assistant,
content: "I'm here to help!".to_string(),
metadata: Some(Metadata {
timestamp: 1234567890,
tokens: 42,
tags: vec!["greeting".to_string(), "helpful".to_string()],
}),
};
let json_value = msg_with_meta.to_json_value().unwrap();
println!(" JSON Value:");
println!(" role: {}", json_value["role"]);
println!(" content: {}", json_value["content"]);
println!(" metadata.tokens: {}", json_value["metadata"]["tokens"]);
println!();
println!("Example 3: Configuration serialization");
let config = Config {
api_key: "sk-ant-api03-xxxx".to_string(),
model: "claude-3-opus-20240229".to_string(),
max_tokens: 1024,
temperature: 0.7,
stop_sequences: vec!["\n\nHuman:".to_string(), "\n\nAssistant:".to_string()],
};
let config_json = config.to_json_string_pretty().unwrap();
println!(" Config JSON:\n{}", indent(&config_json, 4));
println!();
println!("Example 4: Complex nested conversation");
let conversation = Conversation {
id: "conv_123456".to_string(),
messages: vec![
Message {
role: Role::System,
content: "You are a helpful assistant.".to_string(),
metadata: None,
},
Message {
role: Role::User,
content: "What is Rust?".to_string(),
metadata: Some(Metadata {
timestamp: 1234567890,
tokens: 10,
tags: vec!["question".to_string()],
}),
},
Message {
role: Role::Assistant,
content: "Rust is a systems programming language...".to_string(),
metadata: Some(Metadata {
timestamp: 1234567895,
tokens: 50,
tags: vec!["answer".to_string(), "technical".to_string()],
}),
},
],
config: config.clone(),
summary: Some("Discussion about Rust programming language".to_string()),
};
let conv_json = conversation.to_json_string_pretty().unwrap();
println!(
" Conversation JSON (truncated):\n{}",
truncate(&conv_json, 500)
);
println!();
println!("Example 5: Roundtrip serialization");
let original = Message {
role: Role::User,
content: "Test message".to_string(),
metadata: Some(Metadata {
timestamp: 999,
tokens: 5,
tags: vec!["test".to_string()],
}),
};
println!(" Original: {:?}", original);
let json_str = original.to_json_string().unwrap();
println!(" Serialized: {}", json_str);
let deserialized = Message::from_json_string(&json_str).unwrap();
println!(" Deserialized: {:?}", deserialized);
assert_eq!(original, deserialized);
println!(" ✓ Roundtrip successful!");
println!();
println!("Example 6: JSON Value manipulation");
let msg = Message {
role: Role::User,
content: "Original content".to_string(),
metadata: None,
};
let mut json_value = msg.to_json_value().unwrap();
println!(" Original value: {}", json_value);
if let Some(obj) = json_value.as_object_mut() {
obj.insert("content".to_string(), serde_json::json!("Modified content"));
obj.insert("injected_field".to_string(), serde_json::json!(true));
}
println!(" Modified value: {}", json_value);
let modified_msg = Message::from_json_value(json_value).unwrap();
println!(" Back to struct: {:?}", modified_msg);
assert_eq!(modified_msg.content, "Modified content");
println!();
println!("Example 7: Error handling");
let invalid_json = r#"{"role": "user", "content": "test", invalid}"#;
match Message::from_json_string(invalid_json) {
Ok(_) => println!(" Unexpected success"),
Err(e) => println!(" ✓ Parse error caught: {}", e),
}
let type_mismatch = r#"{"role": "user", "content": 123, "metadata": null}"#;
match Message::from_json_string(type_mismatch) {
Ok(_) => println!(" Unexpected success"),
Err(e) => println!(" ✓ Type error caught: {}", e),
}
let missing_field = r#"{"role": "user"}"#;
match Message::from_json_string(missing_field) {
Ok(_) => println!(" Unexpected success"),
Err(e) => println!(" ✓ Missing field error caught: {}", e),
}
println!();
println!("Example 8: Compact vs Pretty");
let large_conversation = Conversation {
id: "perf_test".to_string(),
messages: vec![
Message {
role: Role::User,
content: "A".repeat(100),
metadata: Some(Metadata {
timestamp: 1,
tokens: 100,
tags: vec!["a".to_string(); 10],
}),
};
10
],
config: Config {
api_key: "test".to_string(),
model: "claude-3".to_string(),
max_tokens: 1024,
temperature: 0.5,
stop_sequences: vec![],
},
summary: None,
};
let compact = large_conversation.to_json_string().unwrap();
let pretty = large_conversation.to_json_string_pretty().unwrap();
println!(" Compact size: {} bytes", compact.len());
println!(" Pretty size: {} bytes", pretty.len());
println!(
" Overhead: {:.1}%",
(pretty.len() as f64 / compact.len() as f64 - 1.0) * 100.0
);
println!();
println!("=== Summary ===");
println!("SerializePipeline provides a unified interface for JSON operations.");
println!("All types with #[derive(Serialize, Deserialize)] get it automatically.");
println!("Methods available:");
println!(" - to_json_value() / from_json_value()");
println!(" - to_json_string() / from_json_string()");
println!(" - to_json_string_pretty()");
println!("Zero boilerplate, comprehensive error handling included.");
}
fn indent(text: &str, spaces: usize) -> String {
let prefix = " ".repeat(spaces);
text.lines()
.map(|line| format!("{}{}", prefix, line))
.collect::<Vec<_>>()
.join("\n")
}
fn truncate(text: &str, max_len: usize) -> String {
if text.len() <= max_len {
text.to_string()
} else {
format!(
"{}...\n [truncated {} chars]",
&text[..max_len],
text.len() - max_len
)
}
}