use crate::hook::Hook;
use crate::hexchat::{ Hexchat, Eat, EventAttrs };
use crate::user_data::*;
use core::mem;
use UCallback::*;
#[allow(dead_code)]
enum UCallback {
Command (Box< Callback > ),
Print (Box< PrintCallback > ),
PrintAttrs (Box< PrintAttrsCallback > ),
Timer (Box< TimerCallback > ),
TimerOnce (Box< TimerCallbackOnce > ),
FD (Box< FdCallback > ),
OnceDone,
}
impl Default for UCallback {
fn default() -> Self { OnceDone }
}
pub (crate)
struct CallbackData {
callback : UCallback,
data : UserData,
hook : Hook,
}
impl CallbackData {
pub (crate)
fn new_command_data(callback : Box<Callback>,
data : UserData,
hook : Hook
) -> Self
{
let callback = Command(callback);
CallbackData { callback, data, hook }
}
pub (crate)
fn new_print_data(callback : Box<PrintCallback>,
data : UserData,
hook : Hook
) -> Self
{
let callback = Print(callback);
CallbackData { callback, data, hook }
}
pub (crate)
fn new_print_attrs_data(callback : Box<PrintAttrsCallback>,
data : UserData,
hook : Hook
) -> Self
{
let callback = PrintAttrs(callback);
CallbackData { callback, data, hook }
}
pub (crate)
fn new_timer_data(callback : Box<TimerCallback>,
data : UserData,
hook : Hook
) -> Self
{
let callback = Timer(callback);
CallbackData { callback, data, hook }
}
#[allow(dead_code)]
pub (crate)
fn new_timer_once_data(callback : Box<TimerCallbackOnce>,
data : UserData,
hook : Hook
) -> Self
{
let callback = TimerOnce(callback);
CallbackData { callback, data, hook }
}
pub (crate)
fn new_fd_data(callback : Box<FdCallback>,
data : UserData,
hook : Hook
) -> Self
{
let callback = FD(callback);
CallbackData { callback, data, hook }
}
#[inline]
pub (crate)
fn get_user_data(&self) -> &UserData {
&self.data
}
#[allow(dead_code)]
pub (crate)
fn take_data(&mut self) -> UserData {
mem::take(&mut self.data)
}
#[inline]
pub (crate)
unsafe fn command_cb(&mut self,
hc : &Hexchat,
word : &[String],
word_eol : &[String],
ud : &UserData
) -> Eat
{
if let Command(callback) = &mut self.callback {
(*callback)(hc, word, word_eol, ud)
} else {
panic!("Invoked wrong type in CallbackData.");
}
}
#[inline]
pub (crate)
unsafe fn print_cb(&mut self,
hc : &Hexchat,
word : &[String],
ud : &UserData
) -> Eat
{
if let Print(callback) = &mut self.callback {
(*callback)(hc, word, ud)
} else {
panic!("Invoked wrong type in CallbackData.");
}
}
#[inline]
pub (crate)
unsafe fn print_attrs_cb(&mut self,
hc : &Hexchat,
word : &[String],
attrs : &EventAttrs,
ud : &UserData
) -> Eat
{
if let PrintAttrs(callback) = &mut self.callback {
(*callback)(hc, word, attrs, ud)
} else {
panic!("Invoked wrong type in CallbackData.");
}
}
#[inline]
pub (crate)
unsafe fn timer_cb(&mut self, hc: &Hexchat, ud: &UserData) -> i32
{
if let Timer(callback) = &mut self.callback {
let keep_going = (*callback)(hc, ud);
if keep_going == 0 {
self.hook.unhook();
0
} else {
1
}
} else {
panic!("Invoked wrong type in CallbackData.");
}
}
#[inline]
pub (crate)
unsafe fn timer_once_cb(&mut self, hc: &Hexchat, ud: &UserData) -> i32
{
let variant = mem::take(&mut self.callback);
match variant {
TimerOnce(callback) => {
(callback)(hc, ud);
self.hook.unhook();
0
},
OnceDone => {
panic!("Invoked a one-time callback more than once.");
},
_ => {
panic!("Invoked wrong type in CallbackData.");
},
}
}
#[inline]
pub (crate)
unsafe fn fd_cb(&mut self,
hc : &Hexchat,
fd : i32,
flags : i32,
ud : &UserData) -> Eat
{
if let FD(callback) = &mut self.callback {
(*callback)(hc, fd, flags, ud)
} else {
panic!("Invoked wrong type in CallbackData.");
}
}
}
pub (crate)
type Callback = dyn FnMut(&Hexchat,
&[String],
&[String],
&UserData
) -> Eat;
pub (crate)
type PrintCallback
= dyn FnMut(&Hexchat,
&[String],
&UserData
) -> Eat;
pub (crate)
type PrintAttrsCallback
= dyn FnMut(&Hexchat,
&[String],
&EventAttrs,
&UserData
) -> Eat;
pub (crate)
type TimerCallback
= dyn FnMut(&Hexchat, &UserData) -> i32;
pub (crate)
type TimerCallbackOnce
= dyn FnOnce(&Hexchat, &UserData) -> i32;
pub (crate)
type FdCallback
= dyn FnMut(&Hexchat, i32, i32, &UserData) -> Eat;