canic-utils 0.5.19

Canic — a canister orchestration and management toolkit for the Internet Computer
Documentation

canic-utils

Small, deterministic utilities that Canic (and your canisters) rely on without pulling in the whole stack. These helpers are WASM-safe, avoid std-only randomness, and aim to be predictable across replicas.

What you get:

  • MiniCBOR codecs with clear errors (serialize / deserialize).
  • Fast xxHash3 helpers for non-crypto hashing.
  • Deterministic RNG (tinyrand + shared seed) for tests/sampling.
  • Time helpers (now_*) that work in WASM and native.
  • String casing helpers (snake/constant/title/etc.).
  • Perf counter helper (PERF_LAST) for lightweight timing.
  • WASM hashing (module hash) helpers.

Quick hits

use canic_utils::{hash, rand, serialize, time};

let digest = hash::hash_u64(b"tenant-123");      // fast sharding key
let now = time::now_secs();                      // UNIX seconds (WASM-friendly)
let bytes = serialize::serialize(&["ok"]).?;     // CBOR-encode with clear errors
let sample = rand::next_u64();                   // non-crypto RNG for tests

Determinism notes

  • Hashing: xxHash3 is not cryptographic. Use it for sharding, cache keys, and fingerprints—not for signatures or certified data.
  • RNG: seeded from now_nanos() once per process (shared LazyLock<Mutex<StdRand>>). Good for tests and sampling; not for secrets.
  • Time: now_* wraps api::time() on WASM; SystemTime on native. Casts are clamped to u64 with truncation allowed where noted.

Error handling

  • serialize/deserialize return SerializeError instead of panicking. Downstream macros (impl_storable_*) panic with contextual messages so corrupt stable data is obvious in logs.

Perf helper

use canic_utils::perf::PERF_LAST;
use canic_utils::cdk::api::performance_counter;

let before = PERF_LAST.with(|p| *p.borrow());
let now = performance_counter(1);
let elapsed = now.saturating_sub(before);
PERF_LAST.with(|p| *p.borrow_mut() = now);

Casing helper

use canic_utils::case::{Case, Casing};
assert_eq!("hello_world".to_case(Case::Constant), "HELLO_WORLD");
assert!("Title Case".is_case(Case::Title));

WASM helper

use canic_utils::wasm::get_wasm_hash;
let hash = get_wasm_hash(&[0u8; 16]); // 32-byte SHA-256 of the module

Testing

  • RNG tests cover determinism and basic entropy.
  • Time helpers sanity-check epoch values.
  • Storable macros have round-trip + corrupt-data tests to ensure failures are loud.

Layout

canic-utils/
├─ src/
│  ├─ case/          # casing helpers (snake, constant, title)
│  ├─ format.rs      # tiny fmt helpers
│  ├─ hash.rs        # xxHash3 helpers
│  ├─ instructions.rs# low-level wasm instr helpers
│  ├─ perf.rs        # PERF_LAST counter slot
│  ├─ rand.rs        # tinyrand-based RNG
│  ├─ serialize.rs   # MiniCBOR codecs
│  ├─ time.rs        # now_* helpers
│  └─ wasm.rs        # WASM module hashing helpers
└─ Cargo.toml