#![doc(html_logo_url = "https://kornel.ski/rgb-logo.png")]
#![no_std]
#[cfg(test)]
#[macro_use] extern crate std;
#[cfg(feature = "serde")]
#[macro_use] extern crate serde;
mod internal {
pub mod convert;
pub mod ops;
pub mod pixel;
pub mod rgb;
pub mod rgba;
}
pub mod alt;
pub use crate::internal::convert::*;
pub use crate::internal::ops::*;
pub use crate::internal::pixel::*;
pub use crate::internal::rgb::*;
pub use crate::internal::rgba::*;
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct RGB<ComponentType> {
pub r: ComponentType,
pub g: ComponentType,
pub b: ComponentType,
}
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct RGBA<ComponentType, AlphaComponentType = ComponentType> {
pub r: ComponentType,
pub g: ComponentType,
pub b: ComponentType,
pub a: AlphaComponentType,
}
pub type RGB8 = RGB<u8>;
pub type RGB16 = RGB<u16>;
pub type RGBA8 = RGBA<u8>;
pub type RGBA16 = RGBA<u16>;
#[test]
fn rgb_works() {
let rgb = RGB{r:0u8,g:128,b:255}.clone();
assert_eq!(rgb.b, 255);
assert_eq!(rgb, rgb.iter().map(|ch| ch).collect());
assert_eq!(0, [rgb].as_bytes()[0]);
assert_eq!(128, [rgb].as_bytes()[1]);
assert_eq!(255, [rgb].as_bytes()[2]);
let rgb = RGB16{r:0u16,g:0x7F7F,b:65535};
assert_eq!(rgb.b, 65535);
assert_eq!(rgb.as_slice()[1], 0x7F7F);
assert_eq!(0, [rgb].as_bytes()[0]);
assert_eq!(0, [rgb].as_bytes()[1]);
assert_eq!(0x7F, [rgb].as_bytes()[2]);
assert_eq!(0x7F, [rgb].as_bytes()[3]);
assert_eq!(0xFF, [rgb].as_bytes()[4]);
assert_eq!(0xFF, [rgb].as_bytes()[5]);
assert_eq!("rgb(1,2,3)", format!("{}", RGB::new(1,2,3)));
}
#[test]
fn sub_floats() {
assert_eq!(RGBA{r:2.5_f64, g:-1.5, b:0., a:5.}, RGBA{r:3.5_f64, g:-0.5, b:-2., a:0.} - RGBA{r:1.0_f64, g:1., b:-2., a:-5.});
}
#[test]
fn into() {
let a:RGB8 = RGB{r:0,g:1,b:2};
let b:RGB<i16> = a.into();
let c:RGB<f32> = b.into();
let d:RGB<f32> = a.into();
assert_eq!(c, d);
}
#[test]
fn rgba_works() {
let rgba = RGBA{r:0u8,g:128,b:255,a:33}.clone();
assert_eq!(rgba.b, 255);
assert_eq!(rgba.a, 33);
assert_eq!(rgba, rgba.iter().map(|ch| ch).collect());
assert_eq!("rgba(1,2,3,4)", format!("{}", RGBA::new(1,2,3,4)));
assert_eq!(rgba - rgba, RGBA::new(0,0,0,0));
}
#[test]
fn bytes() {
let rgb = RGB8::new(1,2,3);
let rgb_arr = [rgb];
let rgb_bytes = rgb_arr.as_bytes();
assert_eq!(&[1,2,3], rgb_bytes);
assert_eq!(rgb_bytes.as_rgba().len(), 0);
assert_eq!({let t: &[RGBA8] = rgb_bytes.as_pixels(); t}.len(), 0);
assert_eq!(rgb, rgb_bytes.into_iter().cloned().collect());
assert_eq!(&[rgb], rgb_bytes.as_rgb());
assert_eq!(&[rgb], rgb_bytes.as_pixels());
let mut rgb2 = [rgb];
assert_eq!(rgb2.as_mut_slice().as_rgb_mut(), &mut [rgb]);
assert_eq!(&mut [rgb], rgb2.as_mut_slice().as_pixels_mut());
let rgba = RGBA8::new(1,2,3,4);
let mut rgba_arr = [rgba];
{
let rgba_bytes = rgba_arr.as_bytes_mut();
assert_eq!(&[1,2,3,4], rgba_bytes);
assert_eq!(&[rgba], rgba_bytes.as_rgba());
rgba_bytes[3] = 99;
}
assert_eq!(RGBA8::new(1,2,3,99), rgba_arr.as_bytes().into_iter().cloned().collect());
let rgb = RGB16::new(1,2,3);
let rgb_slice = rgb.as_slice();
assert_eq!(&[1,2,3], rgb_slice);
assert_eq!(rgb_slice.as_rgba(), &[]);
assert_eq!(&[rgb], rgb_slice.as_rgb());
assert_eq!(rgb, rgb_slice.into_iter().cloned().collect());
let rgba = RGBA16::new(1,2,3,4);
let rgba_slice = rgba.as_slice();
assert_eq!(&[1,2,3,4], rgba_slice);
assert_eq!(&[1,2,3], rgba_slice.as_rgb()[0].as_slice());
assert_eq!(&[rgba], rgba_slice.as_rgba());
assert_eq!(rgba, rgba_slice.into_iter().cloned().collect());
let mut rgba2 = [rgba];
assert_eq!(rgba2.as_mut_slice().as_rgba_mut(), &mut [rgba]);
let mut foo = vec![0u8; 8];
foo.as_rgba_mut()[1] = RGBA::new(1,2,3,4);
assert_eq!(&[0u8,0,0,0,1,2,3,4], &foo[..]);
}