🎯 Exemples recommandés
Balanced sample collections from various categories for you to explore
Exemples de Sérialisation de Données Web Rust
Exemples de sérialisation de données Web Rust incluant la sérialisation JSON, la désérialisation et l'analyse XML
💻 Sérialisation JSON rust
🟢 simple
⭐⭐
Sérialiser les objets Rust en chaînes JSON en utilisant serde_json
⏱️ 20 min
🏷️ rust, web, serialization, json
Prerequisites:
Basic Rust, serde, serde_json
// Web Rust JSON Serialization Examples
// Serialize Rust objects to JSON
//
// Add to Cargo.toml:
// [dependencies]
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
use serde::{Deserialize, Serialize, Serializer};
use serde_json::{json, to_string_pretty, Value};
// 1. Basic Serialization
/// Person struct with Serialize derive
#[derive(Debug, Serialize)]
struct Person {
name: String,
age: u32,
email: String,
active: bool,
}
/// Serialize struct to JSON string
fn serialize_to_json<T: Serialize>(value: &T) -> Result<String, serde_json::Error> {
serde_json::to_string(value)
}
/// Serialize struct to pretty JSON string
fn serialize_to_pretty_json<T: Serialize>(value: &T) -> Result<String, serde_json::Error> {
to_string_pretty(value)
}
// 2. Serialize Collections
/// Serialize vector to JSON array
fn serialize_vector(items: &[i32]) -> Result<String, serde_json::Error> {
serde_json::to_string(items)
}
/// Serialize HashMap to JSON object
fn serialize_map(map: &std::collections::HashMap<String, String>) -> Result<String, serde_json::Error> {
serde_json::to_string(map)
}
/// Serialize vector of structs
fn serialize_persons(persons: &[Person]) -> Result<String, serde_json::Error> {
serde_json::to_string(persons)
}
// 3. Custom Serialization
/// Serialize with custom field names
#[derive(Debug, Serialize)]
struct User {
#[serde(rename = "userId")]
id: u32,
#[serde(rename = "userName")]
name: String,
#[serde(rename = "userEmail")]
email: String,
}
/// Serialize with conditionally skipped fields
#[derive(Debug, Serialize)]
struct Product {
id: u32,
name: String,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
tags: Vec<String>,
#[serde(skip_serializing)]
internal_id: String,
}
// 4. Serialize Enums
/// Serialize simple enum
#[derive(Debug, Serialize)]
enum Status {
Active,
Inactive,
Pending,
}
/// Serialize enum with data
#[derive(Debug, Serialize)]
enum Message {
Text(String),
Image { url: String, size: u32 },
Video { url: String, duration: u32 },
}
/// Serialize enum with associated values
#[derive(Debug, Serialize)]
enum Response {
Success(String),
Error { code: u32, message: String },
Empty,
}
// 5. Serialize with Custom Formatting
/// Serialize date as custom format
#[derive(Debug, Serialize)]
struct Event {
name: String,
#[serde(serialize_with = "serialize_date")]
date: chrono::NaiveDate,
}
fn serialize_date<S>(date: &chrono::NaiveDate, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let formatted = date.format("%Y-%m-%d").to_string();
serializer.serialize_str(&formatted)
}
// 6. Serialize to Value
/// Serialize to generic JSON Value
fn serialize_to_value<T: Serialize>(value: &T) -> Result<Value, serde_json::Error> {
serde_json::to_value(value)
}
/// Build JSON object dynamically
fn build_json_object(name: &str, age: u32, email: &str) -> Value {
json!({
"name": name,
"age": age,
"email": email,
"created_at": "2024-01-15"
})
}
/// Build JSON array dynamically
fn build_json_array(items: &[&str]) -> Value {
json!(items)
}
// 7. Serialize with Transformation
/// Serialize with computed field
#[derive(Debug, Serialize)]
struct Invoice {
items: Vec<InvoiceItem>,
#[serde(skip_serializing)]
tax_rate: f64,
#[serde(serialize_with = "serialize_total")]
total: f64,
}
#[derive(Debug, Serialize)]
struct InvoiceItem {
name: String,
quantity: u32,
price: f64,
}
fn serialize_total<S>(total: &f64, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let formatted = format!("{:.2}", total);
serializer.serialize_str(&formatted)
}
// 8. Serialize Nested Structures
/// Serialize nested objects
#[derive(Debug, Serialize)]
struct Company {
name: String,
address: Address,
employees: Vec<Employee>,
}
#[derive(Debug, Serialize)]
struct Address {
street: String,
city: String,
country: String,
postal_code: String,
}
#[derive(Debug, Serialize)]
struct Employee {
id: u32,
name: String,
position: String,
department: String,
}
// 9. Serialize Optional and Null
/// Serialize optional fields
#[derive(Debug, Serialize)]
struct Profile {
username: String,
#[serde(skip_serializing_if = "Option::is_none")]
bio: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
avatar_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
website: Option<String>,
}
// 10. Serialize with Custom Wrapper
/// Serialize with wrapper object
#[derive(Debug, Serialize)]
struct ApiResponse<T> {
success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
message: Option<String>,
data: T,
}
/// Create API response wrapper
fn create_response<T: Serialize>(data: T, message: Option<String>) -> ApiResponse<T> {
ApiResponse {
success: true,
message,
data,
}
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust JSON Serialization Examples ===\n");
// 1. Basic serialization
println!("--- 1. Basic Serialization ---");
let person = Person {
name: "Alice".to_string(),
age: 30,
email: "[email protected]".to_string(),
active: true,
};
println!("Serialized: {}", serialize_to_json(&person)?);
println!("Pretty:\n{}", serialize_to_pretty_json(&person)?);
// 2. Serialize collections
println!("\n--- 2. Serialize Collections ---");
let numbers = vec![1, 2, 3, 4, 5];
println!("Vector: {}", serialize_vector(&numbers)?);
let mut map = std::collections::HashMap::new();
map.insert("key1".to_string(), "value1".to_string());
map.insert("key2".to_string(), "value2".to_string());
println!("Map: {}", serialize_map(&map)?);
// 3. Custom field names
println!("\n--- 3. Custom Field Names ---");
let user = User {
id: 1,
name: "Bob".to_string(),
email: "[email protected]".to_string(),
};
println!("User: {}", serialize_to_pretty_json(&user)?);
// 4. Conditional serialization
println!("\n--- 4. Conditional Serialization ---");
let product = Product {
id: 1,
name: "Laptop".to_string(),
description: Some("High-performance laptop".to_string()),
tags: vec!["electronics".to_string(), "computers".to_string()],
internal_id: "INT-123".to_string(),
};
println!("Product: {}", serialize_to_pretty_json(&product)?);
// 5. Serialize enums
println!("\n--- 5. Serialize Enums ---");
let status = Status::Active;
println!("Status: {}", serialize_to_json(&status)?);
let message = Message::Image {
url: "https://example.com/image.jpg".to_string(),
size: 1024,
};
println!("Message: {}", serialize_to_json(&message)?);
// 6. Dynamic JSON
println!("\n--- 6. Dynamic JSON ---");
let obj = build_json_object("Charlie", 25, "[email protected]");
println!("Dynamic object: {}", to_string_pretty(&obj)?);
let arr = build_json_array(&["apple", "banana", "orange"]);
println!("Dynamic array: {}", to_string_pretty(&arr)?);
// 7. Nested structures
println!("\n--- 7. Nested Structures ---");
let company = Company {
name: "Tech Corp".to_string(),
address: Address {
street: "123 Main St".to_string(),
city: "San Francisco".to_string(),
country: "USA".to_string(),
postal_code: "94102".to_string(),
},
employees: vec![
Employee {
id: 1,
name: "Alice".to_string(),
position: "Developer".to_string(),
department: "Engineering".to_string(),
},
],
};
println!("Company: {}", serialize_to_pretty_json(&company)?);
// 8. Optional fields
println!("\n--- 8. Optional Fields ---");
let profile = Profile {
username: "alice".to_string(),
bio: Some("Software developer".to_string()),
avatar_url: None,
website: Some("https://alice.dev".to_string()),
};
println!("Profile: {}", serialize_to_pretty_json(&profile)?);
// 9. API response wrapper
println!("\n--- 9. API Response Wrapper ---");
let response = create_response(
person,
Some("User retrieved successfully".to_string()),
);
println!("API Response: {}", serialize_to_pretty_json(&response)?);
// 10. Custom transformation
println!("\n--- 10. Custom Transformation ---");
let invoice = Invoice {
items: vec![
InvoiceItem {
name: "Service A".to_string(),
quantity: 2,
price: 100.0,
},
],
tax_rate: 0.1,
total: 220.0,
};
println!("Invoice: {}", serialize_to_pretty_json(&invoice)?);
println!("\n=== All JSON Serialization Examples Completed ===");
Ok(())
}
💻 Désérialisation JSON rust
🟡 intermediate
⭐⭐⭐
Désérialiser les chaînes JSON en objets Rust avec gestion des erreurs
⏱️ 20 min
🏷️ rust, web, serialization, json
Prerequisites:
Intermediate Rust, serde, serde_json
// Web Rust JSON Deserialization Examples
// Deserialize JSON strings to Rust objects
//
// Add to Cargo.toml:
// [dependencies]
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
use serde::{Deserialize, Serialize, Deserializer};
use serde_json::{from_str, Value};
use std::collections::HashMap;
// 1. Basic Deserialization
/// Person struct with Deserialize derive
#[derive(Debug, Deserialize, Serialize)]
struct Person {
name: String,
age: u32,
email: String,
active: bool,
}
/// Deserialize JSON string to struct
fn deserialize_from_json<T: for<'de> Deserialize<'de>>(json: &str) -> Result<T, serde_json::Error> {
from_str(json)
}
// 2. Deserialize Collections
/// Deserialize JSON array to vector
fn deserialize_to_vector(json: &str) -> Result<Vec<i32>, serde_json::Error> {
from_str(json)
}
/// Deserialize JSON object to HashMap
fn deserialize_to_map(json: &str) -> Result<HashMap<String, String>, serde_json::Error> {
from_str(json)
}
/// Deserialize JSON array of objects
fn deserialize_to_persons(json: &str) -> Result<Vec<Person>, serde_json::Error> {
from_str(json)
}
// 3. Flexible Deserialization
/// Deserialize struct with optional fields
#[derive(Debug, Deserialize)]
struct UserProfile {
username: String,
#[serde(default)]
bio: String,
#[serde(default)]
avatar_url: Option<String>,
#[serde(default)]
active: bool,
}
/// Deserialize struct with default values
#[derive(Debug, Deserialize)]
struct Config {
#[serde(default = "default_port")]
port: u16,
#[serde(default)]
host: String,
#[serde(default = "default_timeout")]
timeout: u64,
}
fn default_port() -> u16 { 8080 }
fn default_timeout() -> u64 { 30 }
// 4. Custom Field Names
/// Deserialize with renamed fields
#[derive(Debug, Deserialize)]
struct ApiUser {
#[serde(rename = "userId")]
id: u32,
#[serde(rename = "userName")]
name: String,
#[serde(rename = "userEmail")]
email: String,
}
// 5. Deserialize Enums
/// Deserialize simple enum
#[derive(Debug, Deserialize, Serialize)]
enum Status {
Active,
Inactive,
Pending,
}
/// Deserialize enum with data
#[derive(Debug, Deserialize, Serialize)]
enum Message {
Text(String),
Image { url: String, size: u32 },
Video { url: String, duration: u32 },
}
// 6. Deserialize with Validation
/// Deserialize age with validation
fn deserialize_age<'de, D>(deserializer: D) -> Result<u32, D::Error>
where
D: Deserializer<'de>,
{
let age = u32::deserialize(deserializer)?;
if age > 150 {
return Err(serde::de::Error::custom("Age must be <= 150"));
}
Ok(age)
}
#[derive(Debug, Deserialize)]
struct ValidatedPerson {
name: String,
#[serde(deserialize_with = "deserialize_age")]
age: u32,
email: String,
}
// 7. Deserialize to Dynamic Value
/// Deserialize to generic Value
fn deserialize_to_value(json: &str) -> Result<Value, serde_json::Error> {
from_str(json)
}
/// Extract field from JSON
fn extract_field(json: &str, field: &str) -> Option<Value> {
let v: Value = from_str(json).ok()?;
v.get(field).cloned()
}
/// Extract nested field
fn extract_nested_field(json: &str, path: &[&str]) -> Option<Value> {
let mut v: Value = from_str(json).ok()?;
for key in path {
v = v.get(key)?.clone();
}
Some(v)
}
// 8. Deserialize with Transformation
/// Deserialize and transform date string
fn deserialize_date<'de, D>(deserializer: D) -> Result<chrono::NaiveDate, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d")
.map_err(serde::de::Error::custom)
}
#[derive(Debug, Deserialize)]
struct Event {
name: String,
#[serde(deserialize_with = "deserialize_date")]
date: chrono::NaiveDate,
}
// 9. Deserialize Enums with Tag
/// Deserialize enum with type tag
#[derive(Debug, Deserialize, Serialize)]
enum Animal {
Dog { name: String, breed: String },
Cat { name: String, indoor: bool },
Bird { name: String, can_fly: bool },
}
// 10. Error Handling
/// Deserialize with helpful error message
fn deserialize_safe<T: for<'de> Deserialize<'de>>(json: &str) -> Result<T, String> {
from_str(json).map_err(|e| format!("Failed to deserialize: {}", e))
}
/// Try multiple formats
fn deserialize_flexibly<T: for<'de> Deserialize<'de>>(json: &str) -> Result<T, String> {
// Try standard format
if let Ok(result) = from_str(json) {
return Ok(result);
}
// Try with relaxed rules
// Add more fallback logic here if needed
Err("All deserialization attempts failed".to_string())
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust JSON Deserialization Examples ===\n");
// 1. Basic deserialization
println!("--- 1. Basic Deserialization ---");
let json_person = r#"{"name":"Alice","age":30,"email":"[email protected]","active":true}"#;
let person: Person = deserialize_from_json(json_person)?;
println!("Deserialized: {:?}", person);
// 2. Deserialize collections
println!("\n--- 2. Deserialize Collections ---");
let json_array = r#"[1,2,3,4,5]"#;
let numbers: Vec<i32> = deserialize_to_vector(json_array)?;
println!("Numbers: {:?}", numbers);
let json_object = r#"{"key1":"value1","key2":"value2"}"#;
let map: HashMap<String, String> = deserialize_to_map(json_object)?;
println!("Map: {:?}", map);
// 3. Optional fields
println!("\n--- 3. Optional Fields ---");
let json_profile = r#"{"username":"alice","active":true}"#;
let profile: UserProfile = deserialize_from_json(json_profile)?;
println!("Profile: {:?}", profile);
// 4. Default values
println!("\n--- 4. Default Values ---");
let json_config = r#"{"host":"localhost"}"#;
let config: Config = deserialize_from_json(json_config)?;
println!("Config: {:?}", config);
// 5. Renamed fields
println!("\n--- 5. Renamed Fields ---");
let json_user = r#"{"userId":1,"userName":"Bob","userEmail":"[email protected]"}"#;
let user: ApiUser = deserialize_from_json(json_user)?;
println!("User: {:?}", user);
// 6. Enums
println!("\n--- 6. Deserialize Enums ---");
let json_status = r#""Active""#;
let status: Status = deserialize_from_json(json_status)?;
println!("Status: {:?}", status);
// 7. Dynamic value
println!("\n--- 7. Dynamic Value ---");
let json_dynamic = r#"{"name":"Charlie","age":25,"city":"NYC"}"#;
let v: Value = deserialize_to_value(json_dynamic)?;
println!("Value: {}", v);
if let Some(name) = extract_field(json_dynamic, "name") {
println!("Extracted name: {}", name);
}
// 8. Validation
println!("\n--- 8. Validation ---");
let json_valid = r#"{"name":"David","age":30,"email":"[email protected]"}"#;
match deserialize_from_json::<ValidatedPerson>(json_valid) {
Ok(person) => println!("Valid person: {:?}", person),
Err(e) => println!("Error: {}", e),
}
// 9. Transformation
println!("\n--- 9. Transformation ---");
let json_event = r#"{"name":"Conference","date":"2024-06-15"}"#;
let event: Event = deserialize_from_json(json_event)?;
println!("Event: {:?}", event);
// 10. Error handling
println!("\n--- 10. Error Handling ---");
let invalid_json = r#"{"invalid":"data"}"#;
match deserialize_safe::<Person>(invalid_json) {
Ok(person) => println!("Person: {:?}", person),
Err(e) => println!("Error: {}", e),
}
println!("\n=== All JSON Deserialization Examples Completed ===");
Ok(())
}
💻 Analyse XML rust
🟡 intermediate
⭐⭐⭐
Analyser et manipuler des documents XML en utilisant quick-xml crate
⏱️ 25 min
🏷️ rust, web, serialization, xml
Prerequisites:
Intermediate Rust, quick-xml crate
// Web Rust XML Parsing Examples
// Parse and manipulate XML documents
//
// Add to Cargo.toml:
// [dependencies]
// quick-xml = "0.31"
use quick_xml::events::{Event, BytesStart, BytesEnd, BytesText};
use quick_xml::Writer;
use std::io::Cursor;
// 1. Basic XML Parsing
/// Parse XML and extract element content
fn parse_element_content(xml: &str, element_name: &str) -> Result<Option<String>, Box<dyn std::error::Error>> {
let reader = quick_xml::Reader::from_str(xml);
let mut in_element = false;
let mut content = None;
let mut reader = reader;
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf)? {
Event::Start(ref e) => {
if e.name().as_ref() == element_name.as_bytes() {
in_element = true;
}
}
Event::Text(e) if in_element => {
content = Some(e.unescape()?.into_owned());
}
Event::End(ref e) => {
if e.name().as_ref() == element_name.as_bytes() {
in_element = false;
break;
}
}
Event::Eof => break,
_ => {}
}
buf.clear();
}
Ok(content)
}
/// Extract all elements with specific tag
fn extract_elements(xml: &str, tag: &str) -> Result<Vec<String>, Box<dyn std::error::Error>> {
let reader = quick_xml::Reader::from_str(xml);
let mut elements = Vec::new();
let mut in_target = false;
let mut reader = reader;
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf)? {
Event::Start(ref e) => {
if e.name().as_ref() == tag.as_bytes() {
in_target = true;
}
}
Event::Text(e) if in_target => {
elements.push(e.unescape()?.into_owned());
}
Event::End(ref e) => {
if e.name().as_ref() == tag.as_bytes() {
in_target = false;
}
}
Event::Eof => break,
_ => {}
}
buf.clear();
}
Ok(elements)
}
// 2. Parse XML Attributes
/// Extract attributes from an element
fn extract_attributes(xml: &str, element: &str) -> Result<Vec<(String, String)>, Box<dyn std::error::Error>> {
let reader = quick_xml::Reader::from_str(xml);
let mut attributes = Vec::new();
let mut buf = Vec::new();
let mut reader = reader;
loop {
match reader.read_event_into(&mut buf)? {
Event::Start(e) => {
if e.name().as_ref() == element.as_bytes() {
for attr in e.attributes() {
let attr = attr?;
let key = std::str::from_utf8(attr.key.as_ref())?.to_string();
let value = attr.unescape_value()?.to_string();
attributes.push((key, value));
}
break;
}
}
Event::Eof => break,
_ => {}
}
buf.clear();
}
Ok(attributes)
}
// 3. Parse Nested Structures
/// Person struct parsed from XML
#[derive(Debug)]
struct Person {
name: String,
age: u32,
email: String,
}
/// Parse person from XML
fn parse_person(xml: &str) -> Result<Person, Box<dyn std::error::Error>> {
let reader = quick_xml::Reader::from_str(xml);
let mut current_element = String::new();
let mut name = String::new();
let mut age = String::new();
let mut email = String::new();
let mut reader = reader;
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf)? {
Event::Start(e) => {
current_element = std::str::from_utf8(e.name().as_ref())?.to_string();
}
Event::Text(e) => {
match current_element.as_str() {
"name" => name = e.unescape()?.into_owned(),
"age" => age = e.unescape()?.into_owned(),
"email" => email = e.unescape()?.into_owned(),
_ => {}
}
}
Event::End(_) => {
current_element.clear();
}
Event::Eof => break,
_ => {}
}
buf.clear();
}
Ok(Person {
name,
age: age.parse()?,
email,
})
}
// 4. Build XML
/// Create simple XML element
fn build_element(name: &str, content: &str) -> Result<String, Box<dyn std::error::Error>> {
let mut writer = Writer::new(Cursor::new(Vec::new()));
writer.write_event(Event::Start(BytesStart::new(name)))?;
writer.write_event(Event::Text(BytesText::new(content)))?;
writer.write_event(Event::End(BytesEnd::new(name)))?;
let result = writer.into_inner().into_inner();
Ok(String::from_utf8(result)?)
}
/// Create XML with attributes
fn build_element_with_attrs(
name: &str,
attrs: &[(&str, &str)],
content: &str,
) -> Result<String, Box<dyn std::error::Error>> {
let mut writer = Writer::new(Cursor::new(Vec::new()));
let mut elem = BytesStart::new(name);
for (key, value) in attrs {
elem.push_attribute((*key, *value));
}
writer.write_event(Event::Start(elem))?;
writer.write_event(Event::Text(BytesText::new(content)))?;
writer.write_event(Event::End(BytesEnd::new(name)))?;
let result = writer.into_inner().into_inner();
Ok(String::from_utf8(result)?)
}
// 5. XML to Struct Conversion
/// Book struct
#[derive(Debug)]
struct Book {
title: String,
author: String,
year: u32,
}
/// Parse book from XML
fn parse_book(xml: &str) -> Result<Book, Box<dyn std::error::Error>> {
let reader = quick_xml::Reader::from_str(xml);
let mut current = String::new();
let mut title = String::new();
let mut author = String::new();
let mut year = String::new();
let mut reader = reader;
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf)? {
Event::Start(e) => {
current = std::str::from_utf8(e.name().as_ref())?.to_string();
}
Event::Text(e) => {
match current.as_str() {
"title" => title = e.unescape()?.into_owned(),
"author" => author = e.unescape()?.into_owned(),
"year" => year = e.unescape()?.into_owned(),
_ => {}
}
}
Event::End(_) => current.clear(),
Event::Eof => break,
_ => {}
}
buf.clear();
}
Ok(Book {
title,
author,
year: year.parse()?,
})
}
// 6. Serialize to XML
/// Convert book to XML
fn book_to_xml(book: &Book) -> Result<String, Box<dyn std::error::Error>> {
let mut writer = Writer::new_with_indent(Cursor::new(Vec::new()), b' ', 4);
writer.write_event(Event::Decl(BytesStart::new("version="1.0" encoding="UTF-8"")))?;
let mut root = BytesStart::new("book");
writer.write_event(Event::Start(root))?;
let mut title_elem = BytesStart::new("title");
writer.write_event(Event::Start(title_elem))?;
writer.write_event(Event::Text(BytesText::new(&book.title)))?;
writer.write_event(Event::End(BytesEnd::new("title")))?;
let mut author_elem = BytesStart::new("author");
writer.write_event(Event::Start(author_elem))?;
writer.write_event(Event::Text(BytesText::new(&book.author)))?;
writer.write_event(Event::End(BytesEnd::new("author")))?;
let mut year_elem = BytesStart::new("year");
writer.write_event(Event::Start(year_elem))?;
writer.write_event(Event::Text(BytesText::new(&book.year.to_string())))?;
writer.write_event(Event::End(BytesEnd::new("year")))?;
writer.write_event(Event::End(BytesEnd::new("book")))?;
let result = writer.into_inner().into_inner();
Ok(String::from_utf8(result)?)
}
// 7. Extract CDATA
/// Extract CDATA content
fn extract_cdata(xml: &str) -> Result<Option<String>, Box<dyn std::error::Error>> {
let reader = quick_xml::Reader::from_str(xml);
let mut cdata_content = None;
let mut reader = reader;
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf)? {
Event::CData(e) => {
cdata_content = Some(e.to_string());
break;
}
Event::Eof => break,
_ => {}
}
buf.clear();
}
Ok(cdata_content)
}
// 8. Extract Comments
/// Extract all XML comments
fn extract_comments(xml: &str) -> Result<Vec<String>, Box<dyn std::error::Error>> {
let reader = quick_xml::Reader::from_str(xml);
let mut comments = Vec::new();
let mut reader = reader;
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf)? {
Event::Comment(e) => {
comments.push(e.to_string());
}
Event::Eof => break,
_ => {}
}
buf.clear();
}
Ok(comments)
}
// 9. Build Complex XML
/// Build nested XML structure
fn build_catalog_xml(books: &[Book]) -> Result<String, Box<dyn std::error::Error>> {
let mut writer = Writer::new_with_indent(Cursor::new(Vec::new()), b' ', 2);
writer.write_event(Event::Decl(BytesStart::new("version="1.0" encoding="UTF-8"")))?;
let mut catalog = BytesStart::new("catalog");
writer.write_event(Event::Start(catalog))?;
for book in books {
let mut book_elem = BytesStart::new("book");
writer.write_event(Event::Start(book_elem))?;
// Title
let mut title = BytesStart::new("title");
writer.write_event(Event::Start(title))?;
writer.write_event(Event::Text(BytesText::new(&book.title)))?;
writer.write_event(Event::End(BytesEnd::new("title")))?;
// Author
let mut author = BytesStart::new("author");
writer.write_event(Event::Start(author))?;
writer.write_event(Event::Text(BytesText::new(&book.author)))?;
writer.write_event(Event::End(BytesEnd::new("author")))?;
// Year
let mut year = BytesStart::new("year");
writer.write_event(Event::Start(year))?;
writer.write_event(Event::Text(BytesText::new(&book.year.to_string())))?;
writer.write_event(Event::End(BytesEnd::new("year")))?;
writer.write_event(Event::End(BytesEnd::new("book")))?;
}
writer.write_event(Event::End(BytesEnd::new("catalog")))?;
let result = writer.into_inner().into_inner();
Ok(String::from_utf8(result)?)
}
// Usage Examples
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Web Rust XML Parsing Examples ===\n");
// 1. Parse element content
println!("--- 1. Parse Element Content ---");
let xml = r#"<root><greeting>Hello, World!</greeting></root>"#;
match parse_element_content(xml, "greeting") {
Ok(Some(content)) => println!("Greeting: {}", content),
_ => println!("Not found"),
}
// 2. Extract all elements
println!("\n--- 2. Extract All Elements ---");
let xml = r#"<root><item>Apple</item><item>Banana</item><item>Orange</item></root>"#;
let items = extract_elements(xml, "item")?;
println!("Items: {:?}", items);
// 3. Extract attributes
println!("\n--- 3. Extract Attributes ---");
let xml = r#"<person id="1" name="Alice" age="30" />"#;
let attrs = extract_attributes(xml, "person")?;
println!("Attributes: {:?}", attrs);
// 4. Parse person
println!("\n--- 4. Parse Structured Data ---");
let xml = r#"
<person>
<name>Bob</name>
<age>25</age>
<email>[email protected]</email>
</person>
"#;
let person = parse_person(xml)?;
println!("Person: {:?}", person);
// 5. Build XML
println!("\n--- 5. Build XML ---");
let xml = build_element("message", "Hello, XML!")?;
println!("Simple element: {}", xml);
let xml_with_attrs = build_element_with_attrs(
"user",
&[("id", "1"), ("name", "Alice")],
"Content",
)?;
println!("With attributes: {}", xml_with_attrs);
// 6. Parse and build book
println!("\n--- 6. Book Serialization ---");
let xml = r#"<book><title>Rust Programming</title><author>Steve Klabnik</author><year>2023</year></book>"#;
let book = parse_book(xml)?;
println!("Parsed book: {:?}", book);
let book_xml = book_to_xml(&book)?;
println!("Serialized:\n{}", book_xml);
// 7. Build catalog
println!("\n--- 7. Build Complex XML ---");
let books = vec![
Book {
title: "The Rust Book".to_string(),
author: "Steve Klabnik".to_string(),
year: 2023,
},
Book {
title: "Programming Rust".to_string(),
author: "Jim Blandy".to_string(),
year: 2021,
},
];
let catalog_xml = build_catalog_xml(&books)?;
println!("Catalog:\n{}", catalog_xml);
println!("\n=== All XML Parsing Examples Completed ===");
Ok(())
}