use std::marker::PhantomData;
use time::OffsetDateTime;
#[derive(Debug, Copy, Clone)]
pub struct EventAttrs<'a> {
time: OffsetDateTime,
#[cfg(feature = "__unstable_ircv3_line_in_event_attrs")]
ircv3_line: &'a str,
_lifetime: PhantomData<&'a ()>,
}
impl<'a> EventAttrs<'a> {
pub fn new(
time: OffsetDateTime,
#[cfg(feature = "__unstable_ircv3_line_in_event_attrs")] ircv3_line: &'a str,
) -> Self {
Self {
time,
#[cfg(feature = "__unstable_ircv3_line_in_event_attrs")]
ircv3_line,
_lifetime: PhantomData,
}
}
pub fn time(self) -> OffsetDateTime {
self.time
}
#[cfg(feature = "__unstable_ircv3_line_in_event_attrs")]
pub fn ircv3_line(self) -> &'a str {
self.ircv3_line
}
pub fn with_time(self, time: OffsetDateTime) -> Self {
Self { time, ..self }
}
#[cfg(feature = "__unstable_ircv3_line_in_event_attrs")]
pub fn with_ircv3_line(self, ircv3_line: &'a str) -> Self {
Self { ircv3_line, ..self }
}
}
pub trait Event<const ARGS: usize>: Default + private::EventImpl<ARGS> {}
pub(crate) mod private {
use std::ffi::CStr;
use crate::str::HexStr;
pub trait EventImpl<const ARGS: usize> {
const NAME: &'static CStr;
fn args_from_words<'a>(
word: impl Iterator<Item = &'a HexStr>,
word_eol: impl Iterator<Item = &'a HexStr>,
) -> [&'a HexStr; ARGS];
}
}
macro_rules! count {
() => {
0
};
($a:tt) => {
1
};
($a:tt $b:tt) => {
2
};
($a:tt $b:tt $c:tt) => {
3
};
($a:tt $b:tt $c:tt $d:tt) => {
4
};
($a:tt $b:tt $c:tt $d:tt $e:tt) => {
5
};
}
macro_rules! event {
(
$struct_name:ident,
$event_name:literal,
$event_doc:literal,
$($index:tt : $field_name:literal),*
$(; eol $eol_index:tt : $eol_name:literal)?
) => {
#[doc = "`"]
#[doc = $event_name]
#[doc = "`"]
#[doc = ""]
#[doc = $event_doc]
#[doc = ""]
#[doc = "# Fields"]
$(
#[doc = ""]
#[doc = "- `"]
#[doc = $field_name]
#[doc = "`"]
)*
$(
#[doc = ""]
#[doc = "- `"]
#[doc = $eol_name]
#[doc = "`"]
)?
#[derive(Debug, Copy, Clone, Default)]
pub struct $struct_name;
impl crate::event::Event<{ count!($($index)* $($eol_index)?) }> for $struct_name {}
impl crate::event::private::EventImpl<{ count!($($index)* $($eol_index)?) }> for $struct_name {
const NAME: &'static ::std::ffi::CStr = match ::std::ffi::CStr::from_bytes_with_nul(concat!($event_name, "\0").as_bytes()) {
Ok(name) => name,
Err(_) => unreachable!(),
};
#[allow(dead_code)]
#[allow(unused_variables)]
#[allow(unused_mut)]
fn args_from_words<'a>(
mut word: impl Iterator<Item = &'a crate::str::HexStr>,
mut word_eol: impl Iterator<Item = &'a crate::str::HexStr>,
) -> [&'a crate::str::HexStr; { count!($($index)* $($eol_index)?) }] {
const ARGS: usize = count!($($index)* $($eol_index)?);
[
$(
word
.next()
.unwrap_or_else(|| {
panic!(
"Insufficient fields in event '{}': expected {}, found {}",
$event_name,
ARGS,
$index,
)
}),
)*
$(
word_eol
.nth($eol_index)
.unwrap_or_else(|| {
panic!(
"Insufficient fields in event '{}': expected {}, found {}",
$event_name,
ARGS,
$eol_index,
)
}),
)?
]
}
}
};
}
pub mod print;
pub mod server;