colr-types 0.3.1

Color model ZSTs and marker traits for colr.
Documentation
//! Channel layout types for RGB, luma, and YCbCr color models.

use core::marker::PhantomData;

use crate::{AlphaState, BackingStore, ChannelMap, Straight};

// RGB layouts

macro_rules! define_layout_4 {
    ($name:ident, [$r:expr, $g:expr, $b:expr, $a:expr], $doc:literal) => {
        #[doc = $doc]
        #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
        pub struct $name<A: AlphaState = Straight>(PhantomData<A>);
        impl<A: AlphaState> BackingStore<[f32; 4]> for $name<A> {}
        impl<A: AlphaState> BackingStore<[u8; 4]> for $name<A> {}
        #[cfg(feature = "glam")]
        impl<A: AlphaState> BackingStore<glam::Vec4> for $name<A> {}
        impl<A: AlphaState> ChannelMap<4> for $name<A> {
            const INDICES: [usize; 4] = [$r, $g, $b, $a];
        }
    };
}

macro_rules! define_layout_3 {
    ($name:ident, [$r:expr, $g:expr, $b:expr], $doc:literal) => {
        #[doc = $doc]
        #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
        pub struct $name;
        impl BackingStore<[f32; 3]> for $name {}
        impl BackingStore<[u8; 3]> for $name {}
        #[cfg(feature = "glam")]
        impl BackingStore<glam::Vec3> for $name {}
        #[cfg(feature = "glam")]
        impl BackingStore<glam::Vec3A> for $name {}
        impl ChannelMap<3> for $name {
            const INDICES: [usize; 3] = [$r, $g, $b];
        }
    };
}

define_layout_4!(Rgba, [0, 1, 2, 3], "RGBA layout. R=0 G=1 B=2 A=3.");
define_layout_4!(Bgra, [2, 1, 0, 3], "BGRA layout. B=0 G=1 R=2 A=3.");
define_layout_4!(Argb, [1, 2, 3, 0], "ARGB layout. A=0 R=1 G=2 B=3.");
define_layout_4!(Abgr, [3, 2, 1, 0], "ABGR layout. A=0 B=1 G=2 R=3.");
define_layout_3!(Rgb, [0, 1, 2], "RGB layout. R=0 G=1 B=2.");
define_layout_3!(Bgr, [2, 1, 0], "BGR layout. B=0 G=1 R=2.");

// Luma layout

/// Marks a layout as valid for use with a luma color model.
pub trait LumaLayout: 'static {}

/// Two-channel luma+alpha layout, generic over AlphaState. Y=0 A=1.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct LumaA<A: AlphaState = Straight>(PhantomData<A>);

impl<A: AlphaState> BackingStore<[f32; 2]> for LumaA<A> {}

impl<A: AlphaState> ChannelMap<2> for LumaA<A> {
    const INDICES: [usize; 2] = [0, 1];
}

impl<A: AlphaState> LumaLayout for LumaA<A> {}

#[cfg(feature = "glam")]
impl<A: AlphaState> BackingStore<glam::Vec2> for LumaA<A> {}

// YCbCr layouts

/// Marks a layout as valid for use with a YCbCr color model.
pub trait YCbCrLayout: 'static {}

macro_rules! define_ycbcr_layout {
    ($name:ident, [$y:expr, $cb:expr, $cr:expr], $doc:literal) => {
        #[doc = $doc]
        #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
        pub struct $name;
        impl BackingStore<[f32; 3]> for $name {}
        impl ChannelMap<3> for $name {
            const INDICES: [usize; 3] = [$y, $cb, $cr];
        }
        impl YCbCrLayout for $name {}
    };
}

define_ycbcr_layout!(Ycbcr, [0, 1, 2], "YCbCr layout. Y=0 Cb=1 Cr=2.");
define_ycbcr_layout!(Ycrcb, [0, 2, 1], "YCrCb layout. Y=0 Cr=1 Cb=2.");