use crate::symbol::SymbolId;
use std::fmt;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct OptionalSymbol(u32);
impl OptionalSymbol {
pub const NONE: Self = Self(u32::MAX);
#[must_use]
pub const fn some(symbol: SymbolId) -> Self {
Self(symbol.get())
}
#[must_use]
pub const fn get(self) -> Option<SymbolId> {
if self.0 == u32::MAX {
None
} else {
Some(SymbolId::from_raw(self.0))
}
}
#[must_use]
pub const fn is_none(self) -> bool {
self.0 == u32::MAX
}
#[must_use]
pub const fn is_some(self) -> bool {
self.0 != u32::MAX
}
}
impl Default for OptionalSymbol {
fn default() -> Self {
Self::NONE
}
}
impl From<Option<SymbolId>> for OptionalSymbol {
fn from(symbol: Option<SymbolId>) -> Self {
match symbol {
Some(symbol) => Self::some(symbol),
None => Self::NONE,
}
}
}
impl From<OptionalSymbol> for Option<SymbolId> {
fn from(optional: OptionalSymbol) -> Self {
optional.get()
}
}
impl fmt::Debug for OptionalSymbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.get() {
Some(symbol) => write!(f, "Some({symbol:?})"),
None => f.write_str("None"),
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct OptionalI32(i32);
impl OptionalI32 {
pub const NONE: Self = Self(i32::MIN);
#[must_use]
pub const fn some(value: i32) -> Self {
Self(value)
}
#[must_use]
pub const fn get(self) -> Option<i32> {
if self.0 == i32::MIN {
None
} else {
Some(self.0)
}
}
#[must_use]
pub const fn is_none(self) -> bool {
self.0 == i32::MIN
}
#[must_use]
pub const fn is_some(self) -> bool {
self.0 != i32::MIN
}
}
impl Default for OptionalI32 {
fn default() -> Self {
Self::NONE
}
}
impl From<Option<i32>> for OptionalI32 {
fn from(value: Option<i32>) -> Self {
match value {
Some(value) => Self::some(value),
None => Self::NONE,
}
}
}
impl From<OptionalI32> for Option<i32> {
fn from(optional: OptionalI32) -> Self {
optional.get()
}
}
impl fmt::Debug for OptionalI32 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.get() {
Some(value) => write!(f, "Some({value})"),
None => f.write_str("None"),
}
}
}
#[cfg(test)]
#[path = "value_tests.rs"]
mod tests;