castaway icon indicating copy to clipboard operation
castaway copied to clipboard

Implement cast from lifetime-free to unbound types

Open zheland opened this issue 7 months ago • 0 comments

The TryCast{Mut,Ref,Owned}LifetimeFree traits are implemented for LifetimeFree target types, but not implemented for LifetimeFree source types.

This PR adds TryCast{Mut,Ref,Owned}LifetimeFreeBack traits with source types bounded by LifetimeFree trait.

This makes it possible to upcast types and make specialized builders/decoders/constructors like this:

fn decode_smth<T, const N: usize>(buffer: &[u8]) -> [T; N] {
    fn specialized_impl<const N: usize>(buffer: &[u8]) -> [u8; N] { todo!() }
    fn default_impl<T, const N: usize>(buffer: &[u8]) -> [T; N] { todo!() }

    if cast!(0_u8, T).is_ok() {
        let byte_array: [u8; N] = specialized_impl(buffer);
        cast!(byte_array, [T; N]).expect("unexpected cast failure")
    } else {
        default_impl(buffer)
    }
}

This PR is based on (includes) another PR https://github.com/sagebind/castaway/pull/23 and might require rebase before merging if needed. This PR includes additional tests for both PRs. You can use last commit (https://github.com/sagebind/castaway/commit/7b75e1ea746f78713d6af932577c24cae88acdb2 if not changed) for better diffs related to this PR changes only.

Common implementations for *LifetimeFree::try_cast and *LifetimeFreeBack::try_cast methods are extracted into separate private functions to reduce boilerplate code.

New autoderef ordering: TryCastMutLifetimeFree, TryCastMutLifetimeFreeBack (new), TryCastRefLifetimeFree, TryCastRefLifetimeFreeBack (new), TryCastOwnedLifetimeFree, TryCastOwnedLifetimeFreeBack (new), TryCastSliceMut, TryCastSliceRef, TryCastMut, TryCastRef, TryCastOwned

zheland avatar Jul 03 '24 14:07 zheland