use std::{ collections::{HashMap, HashSet}, sync::{Arc, Mutex}, time::{Duration, SystemTime}, }; use tokio::sync::mpsc; use serde::{Deserialize, Serialize}; // Type alias type Result = std::result::Result>; // Constants const MAX_RETRIES: u32 = 3; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5); // Custom error type #[derive(Debug, thiserror::Error)] pub enum ProcessError { #[error("Validation failed: {0}")] ValidationError(String), #[error("Processing failed: {0}")] ProcessingError(String), #[error(transparent)] Other(#[from] Box), } // Trait definition #[async_trait::async_trait] pub trait DataProcessor { async fn process(&self, data: T) -> Result; fn validate(&self, data: &T) -> bool; } // Struct with lifetime parameter and generic type #[derive(Debug)] pub struct ProcessorState<'a, T> { name: &'a str, data: T, created_at: SystemTime, } // Enum with different variants #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Status { Pending, Active { started_at: SystemTime }, Completed { result: String }, Failed { error: String }, } // Struct implementing trait pub struct ItemProcessor { items: Arc>>, status: Status, tx: mpsc::Sender, } // Trait implementation #[async_trait::async_trait] impl DataProcessor for ItemProcessor { async fn process(&self, data: String) -> Result { if !self.validate(&data) { return Err(Box::new(ProcessError::ValidationError("Invalid data".into()))); } Ok(data.to_uppercase()) } fn validate(&self, data: &String) -> bool { !data.is_empty() } } // Struct with derive macros #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { pub name: String, pub max_items: usize, #[serde(default)] pub timeout: Option, } // Implementation with associated types pub trait Storage { type Item; type Error; fn store(&mut self, item: Self::Item) -> std::result::Result<(), Self::Error>; fn retrieve(&self, id: &str) -> std::result::Result, Self::Error>; } // Struct implementing trait with associated types pub struct MemoryStorage { data: HashMap>, } impl Storage for MemoryStorage { type Item = Vec; type Error = std::io::Error; fn store(&mut self, item: Self::Item) -> std::result::Result<(), Self::Error> { self.data.insert(String::from("default"), item); Ok(()) } fn retrieve(&self, id: &str) -> std::result::Result, Self::Error> { Ok(self.data.get(id).cloned()) } } // Async main function #[tokio::main] async fn main() -> Result<()> { let (tx, mut rx) = mpsc::channel(100); let mut processor = ItemProcessor::new(tx); // Spawn background task tokio::spawn(async move { while let Some(item) = rx.recv().await { println!("Received: {}", item); } }); // Process items processor.add_item("test".into()).await?; let config = Config { name: "test".into(), max_items: 100, timeout: Some(DEFAULT_TIMEOUT), }; println!("Config: {:?}", config); Ok(()) }