It would be nice for mint to provide a trait using an associated type to define a surjective conversion function. This would help crates distinguish normal conversions with From
/Into
and establish an equivalence relationship between mint types and individual math crates.
The trait I have in mind looks something like this:
trait IntoMint {
type MintType;
fn into_mint(&self) -> Self::MintType;
}
You've mentioned before that mint should not have traits. I think I have a compelling use case and I'm not sure how else I can solve it!
Background
I am working on a library named Crevice, which generates std140 versions of structs that are safe to treat as byte slices and upload to the GPU. It depends heavily on mint as the common vector type library and bases all of its conversions on it.
Usage is something like this:
#[derive(AsStd140)]
struct PointLight {
position: mint::Vector3<f32>,
color: mint::Vector3<f32>,
brightness: f32,
}
let light = PointLight {
position: [1.0, 2.0, 3.0].into(),
color: [1.0, 1.0, 1.0].into(),
brightness: 3.0,
};
upload_data_to_gpu(light.as_std140().as_bytes());
One awkward portion of the API is that users need to define their structs using Mint types, Crevice's format-specific types (std140::Vec2
, std430::Mat2
, etc), or plain arrays. Crevice effectively generates a companion struct that looks like this:
struct PointLightStd140 {
position: <mint::Vector3<f32> as AsStd140>::Std140Type,
_pad0: [u8; 4],
color: <mint::Vector3<f32> as AsStd140>::Std140Type,
brightness: <f32 as AsStd140>::Std140Type,
}
At proc macro time, it isn't possible for Crevice to tell which mint type should be converted through for a user's type. Ideally, users would be able to write this definition:
struct PointLight {
position: cgmath::Vector3<f32>,
color: cgmath::Vector3<f32>,
brightness: f32,
}
This could work if Crevice could write this blanket impl for AsStd140
:
impl<T> AsStd140 for T where T: IntoMint {
type Std140Type = <<T as IntoMint>::MintType as AsStd140>::Std140Type;
}
Crevice would need to be changed so that this is the only blanket impl for the trait, but I think that would be okay.