typetui 0.2.1

A terminal-based typing test.
Documentation
use std::thread;
use std::time::Duration;
use std::sync::{mpsc, Arc, Mutex, RwLock};
use std::sync::atomic::{AtomicUsize, Ordering};

fn basic_threads() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("Hi number {} from the spawned thread!", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("Hi number {} from the main thread!", i);
        thread::sleep(Duration::from_millis(1));
    }

    handle.join().unwrap();
}

fn move_closure() {
    let v = vec![1, 2, 3];

    let handle = thread::spawn(move || {
        println!("Here's a vector: {:?}", v);
    });

    handle.join().unwrap();
}

fn message_passing() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
    });

    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}

fn multiple_producers() {
    let (tx, rx) = mpsc::channel();

    let tx1 = tx.clone();
    thread::spawn(move || {
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for val in vals {
            tx1.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    thread::spawn(move || {
        let vals = vec![
            String::from("more"),
            String::from("messages"),
            String::from("for"),
            String::from("you"),
        ];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx {
        println!("Got: {}", received);
    }
}

fn mutex_shared_state() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}

fn rwlock_example() {
    let data = Arc::new(RwLock::new(String::from("Hello")));
    let mut handles = vec![];

    for i in 0..3 {
        let data = Arc::clone(&data);
        let handle = thread::spawn(move || {
            let read_guard = data.read().unwrap();
            println!("Reader {}: {}", i, read_guard);
        });
        handles.push(handle);
    }

    let write_handle = thread::spawn(move || {
        let mut write_guard = data.write().unwrap();
        write_guard.push_str(" World");
    });
    handles.push(write_handle);

    for handle in handles {
        handle.join().unwrap();
    }
}

fn atomic_counter() {
    let counter = Arc::new(AtomicUsize::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            counter.fetch_add(1, Ordering::SeqCst);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Atomic counter: {}", counter.load(Ordering::SeqCst));
}

fn scoped_threads() {
    let mut data = vec![1, 2, 3, 4, 5];
    
    std::thread::scope(|s| {
        s.spawn(|| {
            println!("Thread 1: {:?}", data);
        });
        
        s.spawn(|| {
            for i in &mut data {
                *i *= 2;
            }
        });
    });
    
    println!("After scope: {:?}", data);
}

async fn async_hello() {
    println!("Hello from async!");
}

async fn async_with_delay() {
    println!("Starting async task");
    tokio::time::sleep(Duration::from_millis(100)).await;
    println!("Async task completed");
}

use tokio::sync::mpsc as async_mpsc;

async fn async_channels() {
    let (tx, mut rx) = async_mpsc::channel(100);
    
    tokio::spawn(async move {
        for i in 0..5 {
            tx.send(i).await.unwrap();
        }
    });
    
    while let Some(value) = rx.recv().await {
        println!("Received: {}", value);
    }
}

use tokio::sync::RwLock as AsyncRwLock;

async fn async_rwlock() {
    let data = Arc::new(AsyncRwLock::new(String::from("Hello")));
    
    let read_data = Arc::clone(&data);
    let read_task = tokio::spawn(async move {
        let guard = read_data.read().await;
        println!("Read: {}", guard);
    });
    
    let write_data = Arc::clone(&data);
    let write_task = tokio::spawn(async move {
        let mut guard = write_data.write().await;
        guard.push_str(" World");
    });
    
    let _ = tokio::join!(read_task, write_task);
}

fn thread_pool_pattern() {
    use rayon::prelude::*;
    
    let data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    let sum: i32 = data.par_iter().sum();
    println!("Parallel sum: {}", sum);
    
    let squares: Vec<i32> = data.par_iter()
        .map(|x| x * x)
        .collect();
    println!("Squares: {:?}", squares);
}

fn barrier_example() {
    use std::sync::Barrier;
    
    let barrier = Arc::new(Barrier::new(3));
    let mut handles = vec![];
    
    for i in 0..3 {
        let c = Arc::clone(&barrier);
        let handle = thread::spawn(move || {
            println!("Thread {} before barrier", i);
            c.wait();
            println!("Thread {} after barrier", i);
        });
        handles.push(handle);
    }
    
    for handle in handles {
        handle.join().unwrap();
    }
}

fn main() {
    basic_threads();
    move_closure();
    message_passing();
    multiple_producers();
    mutex_shared_state();
    rwlock_example();
    atomic_counter();
    scoped_threads();
    barrier_example();
}

#[tokio::main]
async fn async_main() {
    async_hello().await;
    async_with_delay().await;
    async_channels().await;
    async_rwlock().await;
}