Spaces:
Paused
Paused
File size: 3,378 Bytes
93d826e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | use std::{
collections::{HashMap, HashSet},
sync::{Arc, Mutex},
time::{Duration, SystemTime},
};
use tokio::sync::mpsc;
use serde::{Deserialize, Serialize};
// Type alias
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
// 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<dyn std::error::Error + Send + Sync>),
}
// Trait definition
#[async_trait::async_trait]
pub trait DataProcessor<T> {
async fn process(&self, data: T) -> Result<T>;
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<Mutex<HashSet<String>>>,
status: Status,
tx: mpsc::Sender<String>,
}
// Trait implementation
#[async_trait::async_trait]
impl DataProcessor<String> for ItemProcessor {
async fn process(&self, data: String) -> Result<String> {
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<Duration>,
}
// 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<Option<Self::Item>, Self::Error>;
}
// Struct implementing trait with associated types
pub struct MemoryStorage {
data: HashMap<String, Vec<u8>>,
}
impl Storage for MemoryStorage {
type Item = Vec<u8>;
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<Option<Self::Item>, 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(())
}
|