#[macro_export]
macro_rules! define_index {
($name:ident, $inner:ty, $doc:expr) => {
#[doc = $doc]
#[repr(transparent)]
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord
)]
pub struct $name($inner);
impl $name {
pub const fn from(var: $inner) -> Self {
Self(var)
}
pub const fn get(&self) -> $inner {
self.0
}
}
impl std::ops::Deref for $name {
type Target = $inner;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<$inner> for $name {
fn from(value: $inner) -> Self {
$name(value)
}
}
impl From<$name> for $inner {
fn from(value: $name) -> Self {
value.0
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
};
}
#[macro_export]
macro_rules! define_nonzero_count {
($name:ident, $base:ty, $doc:expr) => {
#[doc = $doc]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct $name {
value: $base,
}
impl $name {
pub fn new(value: $base) -> Result<Self, FeagiDataError> {
if value == 0 {
return Err(FeagiDataError::BadParameters("Count cannot be zero!".into()));
}
Ok($name{
value,
})
}
}
impl TryFrom<$base> for $name {
type Error = FeagiDataError;
fn try_from(value: $base) -> Result<Self, FeagiDataError> {
$name::new({value})
}
}
impl From<$name> for $base {
fn from(value: $name) -> $base {
value.value
}
}
impl std::ops::Deref for $name {
type Target = $base;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.value.fmt(f)
}
}
}
}
#[macro_export]
macro_rules! define_xy_coordinates {
($name:ident, $var_type:ty, $friendly_name:expr, $doc_string:expr) => {
#[doc = $doc_string]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)]
pub struct $name {
pub x: $var_type,
pub y: $var_type,
}
impl $name {
pub fn new(x: $var_type, y: $var_type) -> Self {
Self { x, y }
}
}
impl From<$name> for ($var_type, $var_type) {
fn from(value: $name) -> Self {
(value.x, value.y)
}
}
impl From<($var_type, $var_type)> for $name {
fn from(value: ($var_type, $var_type)) -> Self {
$name::new(value.0, value.1)
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}({}, {})", $friendly_name, self.x, self.y)
}
}
};
}
#[macro_export]
macro_rules! define_xy_dimensions {
($name:ident, $var_type:ty, $friendly_name:expr, $invalid_zero_value:expr, $doc_string:expr) => {
#[doc = $doc_string]
#[derive(Clone, Debug, PartialEq, Copy, Hash, Eq)]
pub struct $name {
pub width: $var_type,
pub height: $var_type,
}
impl $name {
pub fn new(x: $var_type, y: $var_type) -> Result<Self, FeagiDataError> {
if x == $invalid_zero_value || y == $invalid_zero_value {
return Err(FeagiDataError::BadParameters(format!("Value cannot be {:?} in a {:?}!", $invalid_zero_value, $friendly_name)));
}
Ok(Self { width: x, height: y })
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}<{}, {}>", $friendly_name, self.width, self.height)
}
}
impl From<$name> for ($var_type, $var_type) {
fn from(value: $name) -> Self {
(value.width, value.height)
}
}
impl TryFrom<($var_type, $var_type)> for $name {
type Error = FeagiDataError;
fn try_from(value: ($var_type, $var_type)) -> Result<Self, Self::Error> {
if value.0 == $invalid_zero_value {
return Err(FeagiDataError::BadParameters(format!("X value cannot be zero!")));
}
if value.1 == $invalid_zero_value {
return Err(FeagiDataError::BadParameters(format!("Y value cannot be zero!")));
}
Ok(Self { width: value.0, height: value.1 })
}
}
}
}
#[macro_export]
macro_rules! define_xyz_coordinates {
($name:ident, $var_type:ty, $friendly_name:expr, $doc_string:expr) => {
#[doc = $doc_string]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)]
pub struct $name {
pub x: $var_type,
pub y: $var_type,
pub z: $var_type,
}
impl $name {
pub fn new(x: $var_type, y: $var_type, z: $var_type) -> Self {
Self { x, y, z }
}
}
impl From<$name> for ($var_type, $var_type, $var_type) {
fn from(value: $name) -> Self {
(value.x, value.y, value.z)
}
}
impl From<($var_type, $var_type, $var_type)> for $name {
fn from(value: ($var_type, $var_type, $var_type)) -> Self {
$name::new(value.0, value.1, value.2)
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}({}, {}, {})", $friendly_name, self.x, self.y, self.z)
}
}
};
}
#[macro_export]
macro_rules! define_xyz_dimensions {
($name:ident, $var_type:ty, $friendly_name:expr, $invalid_zero_value:expr, $doc_string:expr) => {
#[doc = $doc_string]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy)]
pub struct $name {
pub width: $var_type,
pub height: $var_type,
pub depth: $var_type,
}
impl $name {
pub fn new(x: $var_type, y: $var_type, z: $var_type) -> Result<Self, FeagiDataError> {
if x == $invalid_zero_value || y == $invalid_zero_value || z == $invalid_zero_value {
return Err(FeagiDataError::BadParameters(format!("Value cannot be {:?} in a {:?}!", $invalid_zero_value, $friendly_name)));
}
Ok(Self { width: x, height: y, depth: z })
}
pub fn number_elements(&self) -> $var_type {
self.width * self.height * self.depth
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}<{}, {}, {}>", $friendly_name, self.width, self.height, self.depth)
}
}
impl From<$name> for ($var_type, $var_type, $var_type) {
fn from(value: $name) -> Self {
(value.width, value.height, value.depth)
}
}
impl TryFrom<($var_type, $var_type, $var_type)> for $name {
type Error = FeagiDataError;
fn try_from(value: ($var_type, $var_type, $var_type)) -> Result<Self, Self::Error> {
if value.0 == $invalid_zero_value {
return Err(FeagiDataError::BadParameters(format!("X value cannot be zero!")));
}
if value.1 == $invalid_zero_value {
return Err(FeagiDataError::BadParameters(format!("Y value cannot be zero!")));
}
if value.2 == $invalid_zero_value {
return Err(FeagiDataError::BadParameters(format!("Z value cannot be zero!")));
}
Ok(Self { width: value.0, height: value.1, depth: value.2 })
}
}
}
}
#[macro_export]
macro_rules! define_xyz_mapping{
($XYZ_a:ident, $XYZ_b:ident) => {
impl From<$XYZ_a> for $XYZ_b {
fn from(a: $XYZ_a) -> Self {
$XYZ_b::new(a.width, a.height, a.depth).unwrap()
}
}
impl From<$XYZ_b> for $XYZ_a {
fn from(b: $XYZ_b) -> Self {
$XYZ_a::new(b.width, b.height, b.depth).unwrap()
}
}
}
}
#[macro_export]
macro_rules! define_xyz_dimension_range {
($name:ident, $var_type:ty, $coordinate_type:ty, $friendly_name:expr, $doc:expr) => {
#[doc = $doc]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct $name {
pub width: std::ops::Range<$var_type>,
pub height: std::ops::Range<$var_type>,
pub depth: std::ops::Range<$var_type>
}
impl $name {
pub fn new(x: std::ops::Range<$var_type>, y: std::ops::Range<$var_type>, z: std::ops::Range<$var_type>) -> Result<Self, FeagiDataError> {
Ok($name {width: x, height: y, depth: z})
}
pub fn verify_coordinate_within_range(&self, coordinate: &$coordinate_type) -> Result<(), FeagiDataError> {
if self.width.contains(&coordinate.width) && self.height.contains(&coordinate.height) && self.depth.contains(&coordinate.depth) {
return Ok(());
}
Err(FeagiDataError::BadParameters(format!("Coordinate {:?} is not contained by this given range of {:?}!", coordinate, self)))
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}<{:?}, {:?}, {:?}>", $friendly_name, self.width, self.height, self.depth)
}
}
};
}