mod has_alpha;
pub use has_alpha::HasAlpha;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "bytemuck", derive(bytemuck::Zeroable, bytemuck::Pod))]
#[repr(transparent)]
pub struct Alpha<T> {
alpha: T,
}
impl<T> Alpha<T> {
#[must_use]
pub const fn new(alpha: T) -> Self {
Self { alpha }
}
#[must_use]
pub const fn alpha(&self) -> T
where
T: Copy,
{
self.alpha
}
#[must_use]
pub fn into_inner(self) -> T {
self.alpha
}
}
impl<T> HasAlpha for Alpha<T>
where
T: Copy,
{
type Component = T;
fn alpha(&self) -> Self::Component {
self.alpha
}
fn set_alpha(&mut self, value: Self::Component) {
self.alpha = value;
}
}
pub type Alpha8 = Alpha<u8>;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub struct AlphaFirst<A, C> {
alpha: A,
color: C,
}
impl<A, C> AlphaFirst<A, C> {
#[must_use]
pub const fn with_color(alpha: A, color: C) -> Self {
Self { alpha, color }
}
#[must_use]
pub const fn alpha(&self) -> A
where
A: Copy,
{
self.alpha
}
#[must_use]
pub const fn color(&self) -> C
where
C: Copy,
{
self.color
}
#[must_use]
pub fn into_inner(self) -> (A, C) {
(self.alpha, self.color)
}
}
#[cfg(feature = "bytemuck")]
#[allow(unsafe_code)]
unsafe impl<A, C> bytemuck::Pod for AlphaFirst<A, C>
where
A: bytemuck::Pod,
C: bytemuck::Pod,
{
}
#[cfg(feature = "bytemuck")]
#[allow(unsafe_code)]
unsafe impl<A, C> bytemuck::Zeroable for AlphaFirst<A, C>
where
A: bytemuck::Zeroable,
C: bytemuck::Zeroable,
{
}
impl<A, C> HasAlpha for AlphaFirst<A, C>
where
A: Copy,
{
type Component = A;
fn alpha(&self) -> Self::Component {
self.alpha
}
fn set_alpha(&mut self, value: Self::Component) {
self.alpha = value;
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub struct AlphaLast<A, C> {
color: C,
alpha: A,
}
impl<A, C> AlphaLast<A, C> {
#[must_use]
pub const fn with_color(alpha: A, color: C) -> Self {
Self { color, alpha }
}
#[must_use]
pub const fn alpha(&self) -> A
where
A: Copy,
{
self.alpha
}
#[must_use]
pub const fn color(&self) -> C
where
C: Copy,
{
self.color
}
#[must_use]
pub fn into_inner(self) -> (C, A) {
(self.color, self.alpha)
}
}
#[cfg(feature = "bytemuck")]
#[allow(unsafe_code)]
unsafe impl<A, C> bytemuck::Pod for AlphaLast<A, C>
where
A: bytemuck::Pod,
C: bytemuck::Pod,
{
}
#[cfg(feature = "bytemuck")]
#[allow(unsafe_code)]
unsafe impl<A, C> bytemuck::Zeroable for AlphaLast<A, C>
where
A: bytemuck::Zeroable,
C: bytemuck::Zeroable,
{
}
impl<A, C> HasAlpha for AlphaLast<A, C>
where
A: Copy,
{
type Component = A;
fn alpha(&self) -> Self::Component {
self.alpha
}
fn set_alpha(&mut self, value: Self::Component) {
self.alpha = value;
}
}
#[cfg(test)]
#[allow(unsafe_code)]
mod tests {
use super::*;
#[test]
fn alpha_is_repr_transparent() {
let alpha = Alpha::new(128u8);
let bytes = unsafe { core::mem::transmute::<Alpha<u8>, [u8; 1]>(alpha) };
assert_eq!(bytes, [128]);
}
#[test]
fn alpha_new() {
let alpha = Alpha::new(128u8);
assert_eq!(alpha.alpha(), 128);
}
#[test]
fn alpha_alpha_trait_accessors() {
let mut alpha = Alpha::new(128u8);
assert_eq!(HasAlpha::alpha(&alpha), 128);
HasAlpha::set_alpha(&mut alpha, 200);
assert_eq!(HasAlpha::alpha(&alpha), 200);
}
#[test]
fn alpha_into_inner() {
let alpha = Alpha::new(255u8);
assert_eq!(alpha.into_inner(), 255);
}
#[test]
fn alpha8_is_repr_transparent_u8() {
let alpha8 = Alpha8::new(128);
let bytes = unsafe { core::mem::transmute::<Alpha8, [u8; 1]>(alpha8) };
assert_eq!(bytes, [128]);
}
#[test]
fn alpha_first_new() {
let alpha_first = AlphaFirst::with_color(128u8, [255, 0, 0]);
assert_eq!(alpha_first.alpha(), 128);
assert_eq!(alpha_first.color(), [255, 0, 0]);
}
#[test]
fn alpha_first_into_inner() {
let alpha_first = AlphaFirst::with_color(128u8, [255, 0, 0]);
assert_eq!(alpha_first.into_inner(), (128, [255, 0, 0]));
}
#[test]
fn alpha_first_repr_c() {
let alpha_first = AlphaFirst::with_color(128u8, [255, 0, 0]);
let bytes =
unsafe { core::mem::transmute::<AlphaFirst<u8, [u8; 3]>, [u8; 4]>(alpha_first) };
assert_eq!(bytes, [128, 255, 0, 0]);
}
#[test]
fn alpha_first_trait_accessors() {
let mut alpha_first = AlphaFirst::with_color(128u8, [255, 0, 0]);
assert_eq!(HasAlpha::alpha(&alpha_first), 128);
HasAlpha::set_alpha(&mut alpha_first, 200);
assert_eq!(HasAlpha::alpha(&alpha_first), 200);
}
#[test]
fn alpha_last_new() {
let alpha_last = AlphaLast::with_color(128u8, [255, 0, 0]);
assert_eq!(alpha_last.alpha(), 128);
assert_eq!(alpha_last.color(), [255, 0, 0]);
}
#[test]
fn alpha_last_into_inner() {
let alpha_last = AlphaLast::with_color(128u8, [255, 0, 0]);
assert_eq!(alpha_last.into_inner(), ([255, 0, 0], 128));
}
#[test]
fn alpha_last_repr_c() {
let alpha_last = AlphaLast::with_color(128u8, [255, 0, 0]);
let bytes = unsafe { core::mem::transmute::<AlphaLast<u8, [u8; 3]>, [u8; 4]>(alpha_last) };
assert_eq!(bytes, [255, 0, 0, 128]);
}
#[test]
fn alpha_last_trait_accessors() {
let mut alpha_last = AlphaLast::with_color(128u8, [255, 0, 0]);
assert_eq!(HasAlpha::alpha(&alpha_last), 128);
HasAlpha::set_alpha(&mut alpha_last, 200);
assert_eq!(HasAlpha::alpha(&alpha_last), 200);
}
}