From 1c1c0d17d513aca56ffdde0f64183f3a44d14d90 Mon Sep 17 00:00:00 2001
From: pyyupsk <pyyupsk@proton.me>
Date: Thu, 2 Jan 2025 11:27:49 +0700
Subject: [PATCH] refactor: change code snippets to new format

---
 .../advanced-patterns/type-safe-builder.md    | 75 ++++++++++++++++
 .../rust/async-programming/rate-limiter.md    | 52 +++++++++++
 snippets/rust/concurrency/thread-pool.md      | 86 +++++++++++++++++++
 .../memory-management/custom-smart-pointer.md | 77 +++++++++++++++++
 .../string-manipulation/string-to-vec-char.md | 15 ++++
 5 files changed, 305 insertions(+)
 create mode 100644 snippets/rust/advanced-patterns/type-safe-builder.md
 create mode 100644 snippets/rust/async-programming/rate-limiter.md
 create mode 100644 snippets/rust/concurrency/thread-pool.md
 create mode 100644 snippets/rust/memory-management/custom-smart-pointer.md
 create mode 100644 snippets/rust/string-manipulation/string-to-vec-char.md

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, Age> {
+    name: Option<String>,
+    age: Option<u32>,
+    _name: PhantomData<Name>,
+    _age: PhantomData<Age>,
+}
+
+pub struct Missing;
+pub struct Set;
+
+#[derive(Debug)]
+pub struct Person {
+    name: String,
+    age: u32,
+}
+
+impl Default for Builder<Missing, Missing> {
+    fn default() -> Self {
+        Self {
+            name: None,
+            age: None,
+            _name: PhantomData,
+            _age: PhantomData,
+        }
+    }
+}
+
+impl<Age> Builder<Missing, Age> {
+    pub fn name(self, name: impl Into<String>) -> Builder<Set, Age> {
+        Builder {
+            name: Some(name.into()),
+            age: self.age,
+            _name: PhantomData,
+            _age: PhantomData,
+        }
+    }
+}
+
+impl<Name> Builder<Name, Missing> {
+    pub fn age(self, age: u32) -> Builder<Name, Set> {
+        Builder {
+            name: self.name,
+            age: Some(age),
+            _name: PhantomData,
+            _age: PhantomData,
+        }
+    }
+}
+
+impl Builder<Set, Set> {
+    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<Semaphore>,
+}
+
+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<dyn FnOnce() + Send + 'static>;
+
+pub struct ThreadPool {
+    workers: Vec<Worker>,
+    sender: Option<mpsc::Sender<Job>>,
+}
+
+struct Worker {
+    id: usize,
+    thread: Option<thread::JoinHandle<()>>,
+}
+
+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<F>(&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<Mutex<mpsc::Receiver<Job>>>) -> 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<T> {
+    ref_count: AtomicUsize,
+    data: UnsafeCell<T>,
+}
+
+pub struct SmartPtr<T> {
+    ptr: Arc<Interior<T>>,
+}
+
+impl<T> SmartPtr<T> {
+    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<T> Clone for SmartPtr<T> {
+    fn clone(&self) -> Self {
+        self.ptr.ref_count.fetch_add(1, Ordering::SeqCst);
+        SmartPtr {
+            ptr: Arc::clone(&self.ptr),
+        }
+    }
+}
+
+impl<T> Drop for SmartPtr<T> {
+    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<T> Deref for SmartPtr<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe { &*self.ptr.data.get() }
+    }
+}
+
+impl<T> DerefMut for SmartPtr<T> {
+    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<char>
+description: Convert a String into a vector of characters
+author: pyyupsk
+tags: rust,string,vector,chars
+---
+
+```rust
+fn string_to_chars(s: &str) -> Vec<char> {
+    s.chars().collect()
+}
+
+// Usage:
+let chars = string_to_chars("Hello"); // ['H', 'e', 'l', 'l', 'o']
+```