looklook 0.9.0

Descriptive signal synthesiser.
// Copyright 2026 Gabriel Bjørnager Jensen.
//
// This file is part of LOOKLOOK.
//
// LOOKLOOK is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free Software
// Foundation, either version 3 of the License, or (at your option) any later ver-
// sion.
//
// LOOKLOOK is distributed in the hope that it will be useful, but WITHOUT ANY WAR-
// RANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
// PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License along
// with LOOKLOOK. If not, see <https://www.gnu.org/licenses/>.

//! The [`Dn`] enumeration.

use std::fmt::{self, Display, Formatter};

/// A data register name.
#[repr(u8)]
#[derive(Copy, Debug)]
#[derive_const(
	Clone,
	Eq,
	Ord,
	PartialEq,
	PartialOrd,
)]
pub enum Dn {
	/// The `D0` register.
	D0 = 0,

	/// The `D1` register.
	D1 = 1,

	/// The `D2` register.
	D2 = 2,

	/// The `D3` register.
	D3 = 3,

	/// The `D4` register.
	D4 = 4,

	/// The `D5` register.
	D5 = 5,

	/// The `D7` register.
	D6 = 6,

	/// The `D7` register.
	D7 = 7,
}

impl Dn {
	/// The minimum data register index (i.e. `D0`.)
	pub const MIN: Self = Self::D0;

	/// The maximum data register index (i.e. `D7`.)
	pub const MAX: Self = Self::D7;

	/// Reinterprets a [`u16`] value as a data register.
	#[inline]
	#[must_use]
	pub const fn from_u16(mut index: u16) -> Self {
		// Mask to `3` bits.
		index &= 0b111;

		match index {
			0 => Self::D0,
			1 => Self::D1,
			2 => Self::D2,
			3 => Self::D3,
			4 => Self::D4,
			5 => Self::D5,
			6 => Self::D6,
			7 => Self::D7,

			_ => {
				unreachable!();
			}
		}
	}

	/// Reinterprets the register index as a [`u16`] scalar index.
	#[inline(always)]
	#[must_use]
	pub const fn as_u16(self) -> u16 {
		self as u16
	}

	/// Retrieves the data index as a [`usize`] value.
	#[inline]
	#[must_use]
	pub const fn as_usize(self) -> usize {
		self.as_u16().into()
	}

	/// Retrieves a textual representation of the register.
	#[inline]
	#[must_use]
	pub const fn as_str(self) -> &'static str {
		match self {
			Self::D0 => "D0",
			Self::D1 => "D1",
			Self::D2 => "D2",
			Self::D3 => "D3",
			Self::D4 => "D4",
			Self::D5 => "D5",
			Self::D6 => "D6",
			Self::D7 => "D7",
		}
	}
}

impl Display for Dn {
	#[inline]
	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
		f.write_str(self.as_str())
	}
}