Skip to main content

nil_core/continent/
size.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use derive_more::Display;
5use nil_util::ConstDeref;
6use serde::{Deserialize, Serialize};
7use std::cmp::Ordering;
8use std::num::NonZeroU8;
9
10#[derive(Copy, Debug, Display, Deserialize, Serialize, ConstDeref)]
11#[derive_const(Clone, PartialEq, Eq, PartialOrd, Ord)]
12#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
13pub struct ContinentSize(NonZeroU8);
14
15impl ContinentSize {
16  pub const MIN: ContinentSize = unsafe { Self::new_unchecked(100) };
17  pub const MAX: ContinentSize = unsafe { Self::new_unchecked(200) };
18
19  pub const fn new(size: u8) -> Self {
20    let size = size
21      .clamp(Self::MIN.0.get(), Self::MAX.0.get())
22      .next_multiple_of(10);
23
24    unsafe { Self::new_unchecked(size) }
25  }
26
27  /// # Safety
28  ///
29  /// The size must be between [`ContinentSize::MIN`] and [`ContinentSize::MAX`].
30  #[inline]
31  pub const unsafe fn new_unchecked(size: u8) -> Self {
32    Self(unsafe { NonZeroU8::new_unchecked(size) })
33  }
34
35  pub const fn clamp(&mut self) {
36    *self = Self(self.0.clamp(Self::MIN.0, Self::MAX.0));
37  }
38}
39
40const impl Default for ContinentSize {
41  fn default() -> Self {
42    Self::MIN
43  }
44}
45
46const impl From<u8> for ContinentSize {
47  fn from(value: u8) -> Self {
48    Self::new(value)
49  }
50}
51
52const impl From<ContinentSize> for u8 {
53  fn from(value: ContinentSize) -> Self {
54    value.0.get()
55  }
56}
57
58const impl From<ContinentSize> for u16 {
59  fn from(value: ContinentSize) -> Self {
60    u16::from(value.0.get())
61  }
62}
63
64const impl From<ContinentSize> for usize {
65  fn from(value: ContinentSize) -> Self {
66    usize::from(value.0.get())
67  }
68}
69
70const impl From<ContinentSize> for i16 {
71  fn from(value: ContinentSize) -> Self {
72    i16::from(value.0.get())
73  }
74}
75
76const impl From<ContinentSize> for f64 {
77  fn from(value: ContinentSize) -> Self {
78    f64::from(value.0.get())
79  }
80}
81
82const impl PartialEq<u8> for ContinentSize {
83  fn eq(&self, other: &u8) -> bool {
84    self.0.get().eq(other)
85  }
86}
87
88const impl PartialEq<usize> for ContinentSize {
89  fn eq(&self, other: &usize) -> bool {
90    usize::from(self.0.get()).eq(other)
91  }
92}
93
94const impl PartialEq<ContinentSize> for usize {
95  fn eq(&self, other: &ContinentSize) -> bool {
96    self.eq(&usize::from(other.0.get()))
97  }
98}
99
100const impl PartialOrd<u8> for ContinentSize {
101  fn partial_cmp(&self, other: &u8) -> Option<Ordering> {
102    self.0.get().partial_cmp(other)
103  }
104}
105
106const impl PartialOrd<usize> for ContinentSize {
107  fn partial_cmp(&self, other: &usize) -> Option<Ordering> {
108    usize::from(self.0.get()).partial_cmp(other)
109  }
110}
111
112const impl PartialOrd<ContinentSize> for usize {
113  fn partial_cmp(&self, other: &ContinentSize) -> Option<Ordering> {
114    self.partial_cmp(&usize::from(other.0.get()))
115  }
116}