impl_accept_upper_bound

Macro impl_accept_upper_bound 

Source
macro_rules! impl_accept_upper_bound {
    {
        $(#[$meta:meta])*
        impl{$($params:tt)*} $Self:ty $({ $($where_bounds:tt)* })?;

        const DESIRED_GENERIC: $usize_d:ty = $DESIRED_GENERIC:expr;
        const EVAL<const $UPPER:ident: $usize_e:ty>: $Output:ty = $EVAL:expr;

    } => { ... };
}
Expand description

Implements AcceptUpperBound by generating a hidden Const implementor.

Generic parameters are passed in braces ({...}) after impl and cannot have a trailing comma. Where bounds are optionally passed in braces after the implementing type.

The example from the crate level documentation can be written manually like this:

use generic_upper_bound as gub;
pub trait MyTrait {
    const SOME_STR: &'static str;
}
impl<A: MyTrait, B: MyTrait> MyTrait for (A, B) {
    const SOME_STR: &'static str = match core::str::from_utf8(
        gub::eval_with_upper_bound::<Concat<A, B>>()
            .split_at(gub::desired_generic::<Concat<A, B>>())
            .0,
    ) {
        Ok(s) => s,
        _ => unreachable!(),
    };
}

struct Concat<A, B>(A, B);
impl<A: MyTrait, B: MyTrait> gub::AcceptUpperBound for Concat<A, B> {
    type Output = &'static [u8];
    // Want to be passed at least the total length of the strings
    const DESIRED_GENERIC: usize = A::SOME_STR.len() + B::SOME_STR.len();
    // Decide on what to do with each generic const
    type Eval<const UPPER: usize> = ConcatImpl<A, B, UPPER>;
}
struct ConcatImpl<A, B, const N: usize>(A, B);
impl<A: MyTrait, B: MyTrait, const N: usize> gub::Const for ConcatImpl<A, B, N> {
    type Type = &'static [u8];
    const VALUE: Self::Type = panic!("...");
}