Procedural macro for creating stable structures and memory manager

Something like stable_store!(BTreeMap, T, U) where T and U are CandidType.

It will handle the memory manager, the memory ids, the stable structure inits, the impl of Storable and return a reference to the RefCell

Good idea?
How hard to pull off?
Would you use it?

Never wrote a procedural macro, but have played with syn crate. I might have a swing at the ball…

Wasn’t as hard as I thought! This just worked

memory_manager!();

stable_btreemap!(STABLE_MAP1, 0, u64, String);
stable_btreemap!(STABLE_MAP2, 1, u64, String);

The macros

#[macro_export]
macro_rules! memory_manager {
    () => {
        thread_local! {
            static __MEMORY_MANAGER__: std::cell::RefCell<
                ic_stable_structures::memory_manager::MemoryManager<ic_stable_structures::DefaultMemoryImpl>
                > = std::cell::RefCell::new(
                    ic_stable_structures::memory_manager::MemoryManager::init(
                        ic_stable_structures::DefaultMemoryImpl::default()
                    )
                );
        }
    };
}

#[macro_export]
macro_rules! stable_btreemap {
    ($store_name:ident, $mem_id:expr, $key_type:ty, $value_type:ty) => {
        thread_local! {
            static $store_name: std::cell::RefCell<
                ic_stable_structures::btreemap::BTreeMap<
                    $key_type, $value_type, ic_stable_structures::memory_manager::VirtualMemory<
                        ic_stable_structures::DefaultMemoryImpl
                    >
                >
            > = std::cell::RefCell::new(
                ic_stable_structures::btreemap::BTreeMap::init(
                    __MEMORY_MANAGER__.with(|mm| mm.borrow().get(ic_stable_structures::memory_manager::MemoryId::new($mem_id)))
                )
            );
        }
    };
}

2 Likes