use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(u8)]
pub enum Placement {
Inline = 0,
Hoist = 1,
Cache = 2,
Group = 3,
}
impl Placement {
pub const ALL: [Self; 4] = [Self::Inline, Self::Hoist, Self::Cache, Self::Group];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Inline => "inline",
Self::Hoist => "hoist",
Self::Cache => "cache",
Self::Group => "group",
}
}
#[must_use]
pub const fn from_str(value: &str) -> Option<Self> {
match value.as_bytes() {
b"inline" => Some(Self::Inline),
b"hoist" => Some(Self::Hoist),
b"cache" => Some(Self::Cache),
b"group" => Some(Self::Group),
_ => None,
}
}
const fn bit(self) -> u8 {
1 << self as u8
}
}
impl fmt::Display for Placement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
pub struct PlacementSet(u8);
impl PlacementSet {
pub const EMPTY: Self = Self(0);
pub const INLINE: Self = Self(Placement::Inline.bit());
const KNOWN: u8 = Placement::Inline.bit()
| Placement::Hoist.bit()
| Placement::Cache.bit()
| Placement::Group.bit();
#[must_use]
pub const fn with(self, placement: Placement) -> Self {
Self(self.0 | placement.bit())
}
#[must_use]
pub const fn contains(self, placement: Placement) -> bool {
self.0 & placement.bit() != 0
}
#[must_use]
pub const fn len(self) -> u32 {
self.0.count_ones()
}
#[must_use]
pub const fn is_empty(self) -> bool {
self.0 == 0
}
#[must_use]
pub const fn bits(self) -> u8 {
self.0
}
#[must_use]
pub const fn from_bits(bits: u8) -> Option<Self> {
if bits & !Self::KNOWN == 0 {
Some(Self(bits))
} else {
None
}
}
pub fn iter(self) -> impl Iterator<Item = Placement> {
Placement::ALL
.into_iter()
.filter(move |placement| self.contains(*placement))
}
}
impl fmt::Display for PlacementSet {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_empty() {
return f.write_str("-");
}
for (index, placement) in self.iter().enumerate() {
if index > 0 {
f.write_str(",")?;
}
f.write_str(placement.as_str())?;
}
Ok(())
}
}