lazy_rc 0.1.3

Provides implementations of Rc<T> and Arc<T> with lazy initialization.
Documentation
/*
 * lazy_rc - Rc<T> and Arc<T> with *lazy* initialization
 * This is free and unencumbered software released into the public domain.
 */
use std::fmt::Debug;
use std::io::Result;
use std::rc::Rc;
use std::thread;
use std::time::Duration;

use chrono::{Timelike, Utc};
use rand::random;

use lazy_rc::LazyRc;

thread_local! {
    static INSTANCE: LazyRc<MyStruct> = LazyRc::empty();
}

#[derive(Debug)]
struct MyStruct {
    _value: u32,
}

impl MyStruct {
    fn new() -> Result<Self> {
        // Simulate a lengthy computation!
        thread::sleep(Duration::from_secs(15));
        Ok(Self { _value: random() })
    }

    /// Returns a thread-local instance that will be created on first access.
    /// If the initialization function fails, then an Error will be returned.
    pub fn instance() -> Result<Rc<Self>> {
        INSTANCE.with(|instance| instance.or_try_init_with(Self::new))
    }
}

fn main() {
    let mut threads = Vec::with_capacity(3);
    for _n in 0..3 {
        threads.push(thread::spawn(|| {
            print_with_timestamp("Start!");
            print_with_timestamp(MyStruct::instance());
            print_with_timestamp(MyStruct::instance());
            print_with_timestamp(MyStruct::instance());
        }));
    }
    threads.drain(..)
        .for_each(|t| t.join().unwrap());
}

fn print_with_timestamp<T>(value: T)
where
    T: Debug,
{
    let now = Utc::now();
    println!(
        "[{:02}:{:02}:{:02}.{:03}] [{:?}] {:?}",
        now.hour(),
        now.minute(),
        now.second(),
        now.nanosecond() / 1000000,
        thread::current().id(),
        value
    );
}