#thread-safe #dynamic-cast #reference-counting #dyn-any #runtime-typed

castbox

A Runtime-Typed Reference-Counted Smart Pointer and Concurrent Programming tools

2 unstable releases

Uses new Rust 2024

new 0.1.1 Nov 4, 2025
0.0.16 Oct 23, 2025
0.0.12 Sep 9, 2025
0.0.10 Aug 27, 2025

#186 in Memory management

Download history 294/week @ 2025-08-03 63/week @ 2025-08-10 425/week @ 2025-08-17 404/week @ 2025-08-24 37/week @ 2025-08-31 204/week @ 2025-09-07 31/week @ 2025-09-14 1/week @ 2025-09-21 11/week @ 2025-09-28 188/week @ 2025-10-05 20/week @ 2025-10-12 259/week @ 2025-10-19 28/week @ 2025-10-26

495 downloads per month

Apache-2.0

70KB
1.5K SLoC

📦 AnyRef — Runtime-Typed Reference-Counted Smart Pointer for Rust

AnyRef is a custom smart pointer similar to Arc, designed for storing dynamically typed (dyn Any) values with strong and weak reference support, runtime downcasting, and optional thread-safe interior mutability.
It is ideal for scenarios where type erasure and runtime polymorphism are needed without exposing generic interfaces.


✨ Features

  • ✅ Runtime type storage via dyn Any
  • 🔁 Strong and weak reference counting
  • 🔐 Optional thread-safe mutability (with internal locking)
  • 🔍 Safe runtime downcasting (try_downcast, try_downcast_mut)
  • 🚫 No generics in the pointer interface
  • 🧠 Suitable for runtime-managed object graphs

⚙️ Example Usage

Basic Allocation and Access

use castbox::AnyRef;

let a = AnyRef::new(42i32);
assert_eq!(a.as_ref::<i32>(), 42);

Runtime Downcasting

use castbox::AnyRef;

let a = AnyRef::new("hello".to_string());
if let Some(s) = a.try_downcast_ref::<String>() {
    assert_eq!(s, "hello");
}

Cloning and Reference Counting

use castbox::AnyRef;

let a = AnyRef::new(vec![1, 2, 3]);
let b = a.clone();

assert_eq!(AnyRef::strong_count(&a), 2);

Weak Reference

use castbox::AnyRef;

let a = AnyRef::new("temporary".to_string());
let w = a.downgrade();

assert!(w.upgrade().is_some());
drop(a);
assert!(w.upgrade().is_none());

Thread-Safe Mode

use castbox::AnyRef;
use crossync::sync::Barrier;
use std::thread;

let x = AnyRef::new(123i32);
let mut handles = vec![];
let barrier = AnyRef::new(Barrier::with_capacity(10, 0));

for i in 0..10 {
    let x_clone = x.clone();
    let barrier_clone = barrier.clone();
    handles.push(thread::spawn(move || {
        barrier_clone.try_downcast_ref::<Barrier>().unwrap().wait();
        let val = x_clone.as_ref::<i32>();
        assert_eq!(*val, 123);
    }));
}

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

assert_eq!(AnyRef::strong_count(&x), 1);
assert_eq!(AnyRef::weak_count(&x), 0);

📦 Installation

Install AnyRef from crates.io Open your Cargo.toml and add:

[dependencies]
castbox = "0.1.1" # or the latest version available 

📄 License

Apache-2.0


Dependencies

~0.3–2MB
~37K SLoC