1use std::{
4 any::Any,
5 num::ParseIntError,
6 sync::{
7 MutexGuard, PoisonError,
8 mpsc::{RecvError, SendError},
9 },
10};
11use thiserror::Error;
12
13use crate::{
14 packet::{
15 Reader, Sender, arp_packet::ArpPacketBuilderError,
16 heartbeat_packet::HeartbeatPacketBuilderError, rst_packet::RstPacketBuilderError,
17 syn_packet::SynPacketBuilderError,
18 },
19 scanners::ScanMessage,
20};
21
22#[derive(Error, Debug)]
24pub enum RLanLibError {
25 #[error("wire error: {_0}")]
27 Wire(String),
28
29 #[error("failed to send notification message: {:#?}", _0)]
31 NotifierSendError(#[from] SendError<Box<ScanMessage>>),
32
33 #[error("failed to get lock on packet reader: {_0}")]
35 PacketReaderLock(String),
36
37 #[error("failed to get lock on packet sender: {_0}")]
39 PacketSenderLock(String),
40
41 #[error("thread error: {_0}")]
43 ThreadError(String),
44
45 #[error("failed to receive message from channel: {:#?}", _0)]
47 ChannelReceive(#[from] RecvError),
48
49 #[error("failed to build ARP packet: {_0}")]
51 ArpPacketBuild(#[from] ArpPacketBuilderError),
52
53 #[error("failed to build RST packet: {_0}")]
55 RstPacketBuild(#[from] RstPacketBuilderError),
56
57 #[error("failed to build SYN packet: {_0}")]
59 SynPacketBuild(#[from] SynPacketBuilderError),
60
61 #[error("failed to build heartbeat packet: {_0}")]
63 HeartbeatPacketBuild(#[from] HeartbeatPacketBuilderError),
64
65 #[error("scanning error: {error} - ip: {:#?}, port: {:#?}", ip, port)]
67 Scan {
68 error: String,
70 ip: Option<String>,
72 port: Option<String>,
74 },
75}
76
77impl From<Box<dyn Any + Send>> for RLanLibError {
78 fn from(value: Box<dyn Any + Send>) -> Self {
79 if let Some(s) = value.downcast_ref::<&'static str>() {
80 Self::ThreadError(format!("Thread panicked with: {}", s))
81 } else if let Some(s) = value.downcast_ref::<String>() {
82 Self::ThreadError(format!("Thread panicked with: {}", s))
83 } else {
84 Self::ThreadError("Thread panicked with an unknown type".into())
85 }
86 }
87}
88
89impl<'a> From<PoisonError<MutexGuard<'a, dyn Reader + 'static>>> for RLanLibError {
90 fn from(value: PoisonError<MutexGuard<'a, dyn Reader + 'static>>) -> Self {
91 Self::PacketReaderLock(value.to_string())
92 }
93}
94
95impl<'a> From<PoisonError<MutexGuard<'a, dyn Sender + 'static>>> for RLanLibError {
96 fn from(value: PoisonError<MutexGuard<'a, dyn Sender + 'static>>) -> Self {
97 Self::PacketSenderLock(value.to_string())
98 }
99}
100
101impl RLanLibError {
102 pub fn from_net_addr_parse_error(ip: &str, error: std::net::AddrParseError) -> Self {
104 Self::Scan {
105 error: error.to_string(),
106 ip: Some(ip.to_string()),
107 port: None,
108 }
109 }
110
111 pub fn from_ipnet_addr_parse_error(ip: &str, error: ipnet::AddrParseError) -> Self {
113 Self::Scan {
114 error: error.to_string(),
115 ip: Some(ip.to_string()),
116 port: None,
117 }
118 }
119
120 pub fn from_port_parse_int_err(port: &str, error: ParseIntError) -> Self {
122 Self::Scan {
123 error: error.to_string(),
124 ip: None,
125 port: Some(port.to_string()),
126 }
127 }
128
129 pub fn from_channel_send_error(e: SendError<ScanMessage>) -> Self {
131 RLanLibError::NotifierSendError(SendError(Box::from(e.0)))
132 }
133}
134
135unsafe impl Send for RLanLibError {}
136unsafe impl Sync for RLanLibError {}
137
138pub type Result<T> = std::result::Result<T, RLanLibError>;