Attribute Macro ref_cast_impl::ref_cast_custom

source ·
#[ref_cast_custom]
Expand description

Create a function for a RefCast-style reference cast. Call site gets control of the visibility, function name, argument name, constness, unsafety, and documentation.

The derive(RefCast) macro produces a trait impl, which means the function names are predefined, and public if your type is public, and not callable in const (at least today on stable Rust). As an alternative to that, derive(RefCastCustom) exposes greater flexibility so that instead of a trait impl, the casting functions can be made associated functions or free functions, can be named what you want, documented, const or unsafe if you want, and have your exact choice of visibility.

use ref_cast::{ref_cast_custom, RefCastCustom};

#[derive(RefCastCustom)]  // does not generate any public API by itself
#[repr(transparent)]
pub struct Frame([u8]);

impl Frame {
    #[ref_cast_custom]  // requires derive(RefCastCustom) on the return type
    pub(crate) const fn new(bytes: &[u8]) -> &Self;

    #[ref_cast_custom]
    pub(crate) fn new_mut(bytes: &mut [u8]) -> &mut Self;
}

// example use of the const fn
const FRAME: &Frame = Frame::new(b"...");

The above shows associated functions, but you might alternatively want to generate free functions:

impl Frame {
    pub fn new<T: AsRef<[u8]>>(bytes: &T) -> &Self {
        #[ref_cast_custom]
        fn ref_cast(bytes: &[u8]) -> &Frame;

        ref_cast(bytes.as_ref())
    }
}