use crate::{
color::{Alpha, Rgb},
sys::NcChannel,
};
#[derive(Clone, Copy, Default, PartialEq, Eq)]
#[repr(transparent)]
pub struct Channel {
pub nc: NcChannel,
}
mod core_impls {
use super::*;
use core::fmt::{self, Write as _};
#[rustfmt::skip]
impl fmt::Display for Channel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = String::new();
if self.is_rgb() {
let _ = write![s, "rgb:{:02X}_{:02X}_{:02X}", self.r(), self.g(), self.b()];
} else if self.is_palindex() {
let _ = write![s, "palindex:{:03}", self.palindex()];
} else {
s += "defaultcolor";
}
write!(f, "{}+{}", s, self.alpha().display_short())
}
}
#[rustfmt::skip]
impl fmt::Debug for Channel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Channel {{{}}}", self)
}
}
impl From<Channel> for NcChannel {
fn from(channel: Channel) -> NcChannel {
channel.nc
}
}
impl From<NcChannel> for Channel {
fn from(nc: NcChannel) -> Channel {
Self { nc }
}
}
macro_rules! impl_from_int_tuple_array {
($( $int:ty ),+) => {
$( impl_from_int_tuple_array![single: $int]; )+
};
(single: $int:ty) => {
impl From<($int, $int, $int)> for Channel {
fn from(tuple: ($int, $int, $int)) -> Channel {
let arr_u8 = [
tuple.0.clamp(0, <$int>::MAX) as u8,
tuple.1.clamp(0, <$int>::MAX) as u8,
tuple.2.clamp(0, <$int>::MAX) as u8,
];
Self::from_rgb(arr_u8)
}
}
impl From<[$int; 3]> for Channel {
fn from(arr: [$int; 3]) -> Channel {
Self::from((arr[0], arr[1], arr[2]))
}
}
impl From<$int> for Channel {
fn from(int: $int) -> Channel {
NcChannel::from_rgb(int.clamp(0, <$int>::MAX) as u32).into()
}
}
};
}
impl_from_int_tuple_array!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
}
impl Channel {
pub fn new() -> Channel {
NcChannel::new().into()
}
pub fn with_default() -> Channel {
NcChannel::with_default().into()
}
pub fn from_rgb(rgb: impl Into<Rgb>) -> Channel {
NcChannel::from_rgb(rgb.into()).into()
}
pub fn from_rgb_alpha(rgb: impl Into<Rgb>, alpha: Alpha) -> Channel {
NcChannel::from_rgb_alpha(rgb.into(), alpha.into()).into()
}
}
impl Channel {
pub fn is_default(&self) -> bool {
self.nc.default_p()
}
pub fn set_default(&mut self, default: bool) {
if default {
self.nc.set_default();
} else {
self.nc.set_not_default();
}
}
}
impl Channel {
pub fn alpha(&self) -> Alpha {
self.nc.alpha().into()
}
pub fn set_alpha(&mut self, alpha: Alpha) {
self.nc.set_alpha(alpha);
}
pub fn is_rgb(&self) -> bool {
self.nc.rgb_p()
}
pub fn rgb(&self) -> Rgb {
self.nc.rgb().into()
}
pub fn r(&self) -> u8 {
self.nc.r()
}
pub fn g(&self) -> u8 {
self.nc.g()
}
pub fn b(&self) -> u8 {
self.nc.b()
}
pub fn set_rgb(&mut self, rgb: impl Into<Rgb>) {
self.nc.set_rgb(rgb.into());
}
pub fn set_r(&mut self, red: impl Into<u8>) {
self.nc.set_r(red.into());
}
pub fn set_g(&mut self, green: impl Into<u8>) {
self.nc.set_r(green.into());
}
pub fn set_b(&mut self, blue: impl Into<u8>) {
self.nc.set_b(blue.into());
}
}
impl Channel {
pub fn is_palindex(&self) -> bool {
self.nc.palindex_p()
}
pub fn palindex(&self) -> u8 {
self.nc.palindex()
}
pub fn set_palindex(&mut self, index: impl Into<u8>) {
self.nc.set_palindex(index.into());
}
}