#specialization

no-std castaway

Safe, zero-cost downcasting for limited compile-time specialization

3 releases

0.1.2 Dec 9, 2021
0.1.1 Sep 26, 2021
0.1.0 Jun 21, 2021

#162 in Rust patterns

Download history 35/week @ 2021-10-05 2565/week @ 2021-10-12 4937/week @ 2021-10-19 5034/week @ 2021-10-26 7726/week @ 2021-11-02 7392/week @ 2021-11-09 8671/week @ 2021-11-16 7870/week @ 2021-11-23 7147/week @ 2021-11-30 7151/week @ 2021-12-07 7059/week @ 2021-12-14 4260/week @ 2021-12-21 5102/week @ 2021-12-28 6950/week @ 2022-01-04 7290/week @ 2022-01-11 5799/week @ 2022-01-18

25,625 downloads per month
Used in 89 crates (via isahc)

MIT license

18KB
157 lines

Castaway

Safe, zero-cost downcasting for limited compile-time specialization.

Crates.io Documentation License Build

Documentation

Please check out the documentation for details how to use Castaway and its limitations. To get you started, here is a really simple, complete example of Castaway in action:

use std::fmt::Display;
use castaway::cast;

/// Like `std::string::ToString`, but with an optimization when `Self` is
/// already a `String`.
///
/// Since the standard library is allowed to use unstable features,
/// `ToString` already has this optimization using the `specialization`
/// feature, but this isn't something normal crates can do.
pub trait FastToString {
    fn fast_to_string(&self) -> String;
}

impl<T: Display + 'static> FastToString for T {
    fn fast_to_string(&self) -> String {
        // If `T` is already a string, then take a different code path.
        // After monomorphization, this check will be completely optimized
        // away.
        if let Some(string) = cast!(self, &String) {
            // Don't invoke the std::fmt machinery, just clone the string.
            string.to_owned()
        } else {
            // Make use of `Display` for any other `T`.
            format!("{}", self)
        }
    }
}

fn main() {
    println!("specialized: {}", String::from("hello").fast_to_string());
    println!("default: {}", "hello".fast_to_string());
}

What is this?

This is an experimental library that implements zero-cost downcasting of types that works on stable Rust. It began as a thought experiment after I had read this pull request and wondered if it would be possible to alter the behavior of a generic function based on a concrete type without using trait objects. I stumbled on the "zero-cost"-ness of my findings by accident while playing around with different implementations and examining the generated assembly of example programs.

The API is somewhat similar to Any in the standard library, but Castaway is instead focused on ergonomic compile-time downcasting rather than runtime downcasting. Unlike Any, Castaway does support safely casting non-'static references in limited scenarios. If you need to store one or more Box<?> objects implementing some trait with the option of downcasting, you are much better off using Any.

License

This project's source code and documentation is licensed under the MIT license. See the LICENSE file for details.

No runtime deps