use super::*;
pub trait CastFrom<T>
{
fn cast_from(value: T) -> Self;
}
impl<C1, C2> CastFrom<C2> for C1
where
C1: Map,
C2: Map<WithType<C1::Item> = Self>,
C1::Item: CastFrom<C2::Item>,
{
fn cast_from(value: C2) -> Self { value.map(|v| C1::Item::cast_from(v)) }
}
pub trait CastInto<T>: Sized
{
fn cast_into(self) -> T;
}
impl<S, T> CastInto<T> for S
where
T: CastFrom<S>,
{
fn cast_into(self) -> T { T::cast_from(self) }
}
macro_rules! impl_cast_to {
($src: ty, $dest: ty) => {
impl CastFrom<$src> for $dest
{
fn cast_from(value: $src) -> $dest { value as $dest }
}
};
($cast_into: ty) => {
map_on_number!(impl_cast_to, $cast_into);
};
}
map_on_number!(impl_cast_to);
map_on_integer!(
($itself: ty) =>
{
impl CastFrom<bool> for $itself
{
fn cast_from(value: bool) -> $itself { if value { 1 } else { 0 } }
}
impl CastFrom<$itself> for bool
{
fn cast_from(value: $itself) -> bool { value != (0) }
}
};
);
map_on_float!(
($itself: ty) =>
{
impl CastFrom<bool> for $itself
{
fn cast_from(value: bool) -> $itself { if value { 1. } else { 0. } }
}
impl CastFrom<$itself> for bool
{
fn cast_from(value: $itself) -> bool { value as $itself >= 0.5 }
}
};
);
impl CastFrom<bool> for bool
{
fn cast_from(value: bool) -> Self { value }
}
trait_marker!(
CastIntoFloat: CastInto<f32> + ToF32<Output = f32> + CastInto<f64> + ToF64<Output = f64>
);
trait_marker!(
CastFromFloat: CastFrom<f32> + CastFrom<f64>
);
trait_marker!(
CastFloat: CastIntoFloat + CastFromFloat
);
trait_marker!(
CastIntoIntegerUnsigned:
CastInto<u8 > + ToU8<Output = u8> +
CastInto<u16> + ToU16<Output = u16> +
CastInto<u32> + ToU32<Output = u32> +
CastInto<u64> + ToU64<Output = u64> +
CastInto<usize> + ToUSize<Output = usize> +
);
trait_marker!(
CastFromIntegerUnsigned:
CastFrom<u8 > +
CastFrom<u16> +
CastFrom<u32> +
CastFrom<u64> +
CastFrom<usize>
);
trait_marker!(
CastIntegerUnsigned: CastFromIntegerUnsigned + CastFromIntegerUnsigned
);
trait_marker!(
CastIntoIntegerSigned:
CastInto<i8 > + ToI8<Output = i8> +
CastInto<i16> + ToI16<Output = i16> +
CastInto<i32> + ToI32<Output = i32> +
CastInto<i64> + ToI64<Output = i64> +
CastInto<isize> + ToISize<Output = isize>
);
trait_marker!(
CastFromIntegerSigned:
CastFrom<i8 > +
CastFrom<i16> +
CastFrom<i32> +
CastFrom<i64> +
CastFrom<isize>
);
trait_marker!(
CastIntegerSigned: CastFromIntegerSigned + CastFromIntegerUnsigned
);
trait_marker!(
CastIntoInteger: CastIntoIntegerSigned + CastIntoIntegerUnsigned
);
trait_marker!(
CastFromInteger: CastFromIntegerSigned + CastFromIntegerUnsigned
);
trait_marker!(
CastInteger: CastIntoInteger + CastFromInteger
);
trait_marker!(
CastIntoBool: CastInto<bool> + ToBool<Output = bool>
);
trait_marker!(
CastFromBool: CastFrom<bool>
);
trait_marker!(
CastBool: CastIntoBool + CastFromBool
);
trait_marker!(
CastIntoNumber: CastIntoInteger + CastIntoFloat
);
trait_marker!(
CastFromNumber: CastFromInteger + CastFromFloat
);
trait_marker!(
CastNumber: CastInteger + CastFloat
);
trait_marker!(
CastIntoPrimitive: CastIntoNumber + CastIntoBool
);
trait_marker!(
CastFromPrimitive: CastFromNumber + CastFromBool
);
trait_marker!(
CastPrimitive: CastIntoPrimitive + CastFromPrimitive
);