diff --git a/snippets/rust/advanced-patterns/type-safe-builder.md b/snippets/rust/advanced-patterns/type-safe-builder.md new file mode 100644 index 00000000..572f12be --- /dev/null +++ b/snippets/rust/advanced-patterns/type-safe-builder.md @@ -0,0 +1,75 @@ +--- +title: Type-Safe Builder Pattern +description: Implements a compile-time type-safe builder pattern using phantom types +author: pyyupsk +tags: rust,design-pattern,builder,type-safe +--- + +```rust +use std::marker::PhantomData; + +#[derive(Debug)] +pub struct Builder { + name: Option, + age: Option, + _name: PhantomData, + _age: PhantomData, +} + +pub struct Missing; +pub struct Set; + +#[derive(Debug)] +pub struct Person { + name: String, + age: u32, +} + +impl Default for Builder { + fn default() -> Self { + Self { + name: None, + age: None, + _name: PhantomData, + _age: PhantomData, + } + } +} + +impl Builder { + pub fn name(self, name: impl Into) -> Builder { + Builder { + name: Some(name.into()), + age: self.age, + _name: PhantomData, + _age: PhantomData, + } + } +} + +impl Builder { + pub fn age(self, age: u32) -> Builder { + Builder { + name: self.name, + age: Some(age), + _name: PhantomData, + _age: PhantomData, + } + } +} + +impl Builder { + pub fn build(self) -> Person { + Person { + name: self.name.unwrap(), + age: self.age.unwrap(), + } + } +} + +// Usage: +let person = Builder::default() + .name("John") + .age(30) + .build(); +``` diff --git a/snippets/rust/async-programming/rate-limiter.md b/snippets/rust/async-programming/rate-limiter.md new file mode 100644 index 00000000..09ebbc32 --- /dev/null +++ b/snippets/rust/async-programming/rate-limiter.md @@ -0,0 +1,52 @@ +--- +title: Async Rate Limiter +description: Implementation of a token bucket rate limiter for async operations +author: pyyupsk +tags: rust,async,rate-limiter,tokio +--- + +```rust +use std::sync::Arc; +use tokio::sync::Semaphore; +use tokio::time::{interval, Duration}; + +pub struct RateLimiter { + semaphore: Arc, +} + +impl RateLimiter { + pub fn new(rate: u32, interval: Duration) -> Self { + let semaphore = Arc::new(Semaphore::new(rate as usize)); + let sem_clone = semaphore.clone(); + + tokio::spawn(async move { + let mut ticker = interval(interval); + loop { + ticker.tick().await; + sem_clone.add_permits(rate as usize); + } + }); + + RateLimiter { semaphore } + } + + pub async fn acquire(&self) -> RateLimit { + let permit = self.semaphore.acquire().await.unwrap(); + RateLimit { _permit: permit } + } +} + +pub struct RateLimit<'a> { + _permit: tokio::sync::SemaphorePermit<'a>, +} + +// Usage: +async fn example() { + let limiter = RateLimiter::new(10, Duration::from_secs(1)); + + for i in 0..20 { + let _permit = limiter.acquire().await; + println!("Executing task {}", i); + } +} +``` diff --git a/snippets/rust/concurrency/thread-pool.md b/snippets/rust/concurrency/thread-pool.md new file mode 100644 index 00000000..fa84c535 --- /dev/null +++ b/snippets/rust/concurrency/thread-pool.md @@ -0,0 +1,86 @@ +--- +title: Thread Pool Implementation +description: A simple thread pool implementation for parallel task execution +author: pyyupsk +tags: rust,concurrency,thread-pool,parallel +--- + +```rust +use std::sync::{mpsc, Arc, Mutex}; +use std::thread; + +type Job = Box; + +pub struct ThreadPool { + workers: Vec, + sender: Option>, +} + +struct Worker { + id: usize, + thread: Option>, +} + +impl ThreadPool { + pub fn new(size: usize) -> ThreadPool { + assert!(size > 0); + + let (sender, receiver) = mpsc::channel(); + let receiver = Arc::new(Mutex::new(receiver)); + let mut workers = Vec::with_capacity(size); + + for id in 0..size { + workers.push(Worker::new(id, Arc::clone(&receiver))); + } + + ThreadPool { + workers, + sender: Some(sender), + } + } + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + let job = Box::new(f); + self.sender.as_ref().unwrap().send(job).unwrap(); + } +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let message = receiver.lock().unwrap().recv(); + + match message { + Ok(job) => { + println!("Worker {id} got a job; executing."); + job(); + } + Err(_) => { + println!("Worker {id} disconnected; shutting down."); + break; + } + } + }); + + Worker { + id, + thread: Some(thread), + } + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + drop(self.sender.take()); + + for worker in &mut self.workers { + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} +``` diff --git a/snippets/rust/memory-management/custom-smart-pointer.md b/snippets/rust/memory-management/custom-smart-pointer.md new file mode 100644 index 00000000..c92628d0 --- /dev/null +++ b/snippets/rust/memory-management/custom-smart-pointer.md @@ -0,0 +1,77 @@ +--- +title: Custom Smart Pointer +description: Implementation of a custom reference-counted smart pointer with interior mutability +author: pyyupsk +tags: rust,smart-pointer,memory-management,unsafe +--- + +```rust +use std::cell::UnsafeCell; +use std::ops::{Deref, DerefMut}; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; + +pub struct Interior { + ref_count: AtomicUsize, + data: UnsafeCell, +} + +pub struct SmartPtr { + ptr: Arc>, +} + +impl SmartPtr { + pub fn new(data: T) -> Self { + SmartPtr { + ptr: Arc::new(Interior { + ref_count: AtomicUsize::new(1), + data: UnsafeCell::new(data), + }), + } + } + + pub fn get_ref_count(&self) -> usize { + self.ptr.ref_count.load(Ordering::SeqCst) + } +} + +impl Clone for SmartPtr { + fn clone(&self) -> Self { + self.ptr.ref_count.fetch_add(1, Ordering::SeqCst); + SmartPtr { + ptr: Arc::clone(&self.ptr), + } + } +} + +impl Drop for SmartPtr { + fn drop(&mut self) { + if self.ptr.ref_count.fetch_sub(1, Ordering::SeqCst) == 1 { + // Last reference is being dropped + unsafe { + drop(Box::from_raw(self.ptr.data.get())); + } + } + } +} + +impl Deref for SmartPtr { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { &*self.ptr.data.get() } + } +} + +impl DerefMut for SmartPtr { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { &mut *self.ptr.data.get() } + } +} + +// Usage: +let ptr = SmartPtr::new(42); +let cloned = ptr.clone(); +assert_eq!(ptr.get_ref_count(), 2); +assert_eq!(*ptr, 42); +``` diff --git a/snippets/rust/string-manipulation/string-to-vec-char.md b/snippets/rust/string-manipulation/string-to-vec-char.md new file mode 100644 index 00000000..860d3963 --- /dev/null +++ b/snippets/rust/string-manipulation/string-to-vec-char.md @@ -0,0 +1,15 @@ +--- +title: String to Vec +description: Convert a String into a vector of characters +author: pyyupsk +tags: rust,string,vector,chars +--- + +```rust +fn string_to_chars(s: &str) -> Vec { + s.chars().collect() +} + +// Usage: +let chars = string_to_chars("Hello"); // ['H', 'e', 'l', 'l', 'o'] +```