#[cfg(feature = "chumsky")]
use chumsky::{IterParser as _, Parser, text::digits};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[expect(
clippy::module_name_repetitions,
reason = "this type is used outside of this module"
)]
pub struct ChatChannel(pub i32);
#[cfg(feature = "chumsky")]
#[must_use]
#[expect(
clippy::module_name_repetitions,
reason = "this parser is used outside of this module"
)]
pub fn chat_channel_parser<'src>()
-> impl Parser<'src, &'src str, ChatChannel, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
{
digits(10).collect::<String>().try_map(|d, span| {
let d: i32 = d
.parse()
.map_err(|e| chumsky::error::Rich::custom(span, format!("{e:?}")))?;
Ok(ChatChannel(d))
})
}
impl std::fmt::Display for ChatChannel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::str::FromStr for ChatChannel {
type Err = <i32 as std::str::FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
<i32 as std::str::FromStr>::from_str(s).map(ChatChannel)
}
}
pub const PUBLIC_CHANNEL: ChatChannel = ChatChannel(0);
pub const COMBAT_CHANNEL: ChatChannel = ChatChannel(0x7FFF_FFFE);
pub const DEBUG_CHANNEL: ChatChannel = ChatChannel(0x7FFF_FFFF);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, strum::EnumIs)]
#[expect(
clippy::module_name_repetitions,
reason = "this type is used outside of this module"
)]
pub enum ChatVolume {
Whisper,
Say,
Shout,
RegionSay,
}
impl ChatVolume {
#[must_use]
pub fn volume_and_message(s: String) -> (Self, String) {
if let Some(whisper_message) = s.strip_prefix("whispers: ") {
(Self::Whisper, whisper_message.to_string())
} else if let Some(shout_message) = s.strip_prefix("shouts: ") {
(Self::Shout, shout_message.to_string())
} else {
(Self::Say, s)
}
}
}