ic-memory 0.35.5

Durable stable-memory allocation governance for Internet Computer canisters
Documentation
use ic_memory::RuntimeMemory;
use ic_stable_structures::DefaultMemoryImpl;
use std::{
    cell::RefCell,
    sync::atomic::{AtomicBool, Ordering},
};

static EAGER_INIT_RAN: AtomicBool = AtomicBool::new(false);
const MACRO_AUTHORITY: &str = "runtime_macros";

ic_memory::ic_memory_declaration!(authority = MACRO_AUTHORITY, key = "macro.logical.rows.v1");

ic_memory::eager_init!({
    EAGER_INIT_RAN.store(true, Ordering::SeqCst);
});

thread_local! {
    static MACRO_MEMORY: RefCell<Option<RuntimeMemory<DefaultMemoryImpl>>> = {
        assert!(
            ic_memory::is_default_memory_manager_bootstrapped()
                .expect("default runtime lifecycle")
        );
        RefCell::new(Some(ic_memory::ic_memory_key!(authority = MACRO_AUTHORITY, key = "macro.integration.users.v1")
        .expect("committed macro memory")))
    };
}

fn bootstrap_and_require_thread_local_ledger() {
    let validated = ic_memory::bootstrap_default_memory_manager(&pool()).expect("bootstrap");
    ic_memory::default_memory_manager_diagnostic_export()
        .expect("bootstrapped runtime should expose its local ledger");

    assert!(EAGER_INIT_RAN.load(Ordering::SeqCst));
    assert!(
        validated
            .declarations()
            .iter()
            .any(|declaration| declaration.stable_key().as_str() == "macro.integration.users.v1")
    );
    let logical = ic_memory::open_default_memory_manager_memory("macro.logical.rows.v1")
        .expect("key-only host adoption");
    assert_eq!(ic_stable_structures::Memory::size(&logical), 0);
    assert_eq!(
        validated
            .slot_for(&ic_memory::StableKey::parse("macro.logical.rows.v1").unwrap())
            .unwrap()
            .id(),
        11
    );
    MACRO_MEMORY.with(|memory| assert!(memory.borrow().is_some()));
    ic_memory::open_default_memory_manager_memory("macro.integration.users.v1")
        .expect("open macro memory");
}

#[test]
fn first_libtest_default_runtime_bootstraps_its_own_memory() {
    bootstrap_and_require_thread_local_ledger();
}

#[test]
fn second_libtest_default_runtime_bootstraps_its_own_memory() {
    bootstrap_and_require_thread_local_ledger();
}

fn pool() -> ic_memory::MemoryAllocationPool {
    ic_memory::MemoryAllocationPool::new(
        vec![ic_memory::MemoryAuthority::new("runtime_macros", "macro.").unwrap()],
        vec![],
    )
    .unwrap()
}