use crate::context::Context; use crate::error::Result; use crate::payload::{FromPayload, IntoPayload}; use crate::prelude::{IPCError, IPCResult}; use byteorder::{BigEndian, ReadBytesExt}; use bytes::{BufMut, Bytes, BytesMut}; use std::error::Error; use std::fmt::{Display, Formatter}; use std::io::Read; pub static ERROR_EVENT_NAME: &str = "error"; pub static END_EVENT_NAME: &str = "end"; /// Data returned on error event. /// The error event has a default handler that just logs that /// an error occurred. For a custom handler, register a handler on /// the [ERROR_EVENT_NAME] event. #[derive(Clone, Debug)] pub struct ErrorEventData { pub code: u16, pub message: String, } impl Error for ErrorEventData {} impl Display for ErrorEventData { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "IPC Code {}: '{}'", self.code, self.message) } } impl IntoPayload for ErrorEventData { fn into_payload(self, _: &Context) -> IPCResult { let mut buf = BytesMut::new(); buf.put_u16(self.code); buf.put_u32(self.message.len() as u32); buf.put(Bytes::from(self.message)); Ok(buf.freeze()) } } impl FromPayload for ErrorEventData { fn from_payload(mut reader: R) -> Result { let code = reader.read_u16::()?; let message_len = reader.read_u32::()?; let mut message_buf = vec![0u8; message_len as usize]; reader.read_exact(&mut message_buf)?; let message = String::from_utf8(message_buf).map_err(|_| IPCError::CorruptedEvent)?; Ok(ErrorEventData { code, message }) } }