1use std::{error, fmt, io};
4
5use futures::channel::mpsc::SendError;
6use rasn::ber;
7use rasn_ldap::{BindResponse, LdapResult, ResultCode};
8
9use crate::{channel::ChannelError, filter::Rule};
10
11#[derive(Debug)]
13pub struct OperationError {
14 pub result_code: ResultCode,
16 pub matched_dn: String,
18 pub diagnostic_message: String,
20}
21
22impl From<BindResponse> for OperationError {
23 fn from(r: BindResponse) -> Self {
24 OperationError {
25 result_code: r.result_code,
26 matched_dn: r.matched_dn.0,
27 diagnostic_message: r.diagnostic_message.0,
28 }
29 }
30}
31
32impl From<LdapResult> for OperationError {
33 fn from(r: LdapResult) -> Self {
34 OperationError {
35 result_code: r.result_code,
36 matched_dn: r.matched_dn.0,
37 diagnostic_message: r.diagnostic_message.0,
38 }
39 }
40}
41
42#[derive(Debug)]
44#[allow(clippy::large_enum_variant)]
45pub enum Error {
46 Io(io::Error),
47 AsnDecode(ber::de::DecodeError),
48 AsnEncode(ber::enc::EncodeError),
49 Channel(ChannelError),
50 Send(SendError),
51 InvalidMessageId,
52 OperationFailed(OperationError),
53 InvalidFilter(pest::error::Error<Rule>),
54 InvalidResponse,
55 ConnectionClosed,
56 GssApiError(String),
57 NoSaslCredentials,
58}
59
60impl error::Error for Error {}
61
62impl From<io::Error> for Error {
63 fn from(e: io::Error) -> Self {
64 Error::Io(e)
65 }
66}
67
68impl From<ber::de::DecodeError> for Error {
69 fn from(e: ber::de::DecodeError) -> Self {
70 Error::AsnDecode(e)
71 }
72}
73
74impl From<ber::enc::EncodeError> for Error {
75 fn from(e: ber::enc::EncodeError) -> Self {
76 Error::AsnEncode(e)
77 }
78}
79
80impl From<ChannelError> for Error {
81 fn from(e: ChannelError) -> Self {
82 Error::Channel(e)
83 }
84}
85
86impl From<SendError> for Error {
87 fn from(e: SendError) -> Self {
88 Error::Send(e)
89 }
90}
91
92impl From<pest::error::Error<Rule>> for Error {
93 fn from(e: pest::error::Error<Rule>) -> Self {
94 Error::InvalidFilter(e)
95 }
96}
97
98impl fmt::Display for Error {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 match self {
101 Error::Io(e) => write!(f, "{e}"),
102 Error::AsnDecode(e) => write!(f, "{e:?}"),
103 Error::AsnEncode(e) => write!(f, "{e:?}"),
104 Error::Channel(e) => write!(f, "{e}"),
105 Error::Send(e) => write!(f, "{e}"),
106 Error::InvalidMessageId => write!(f, "Invalid message id"),
107 Error::OperationFailed(code) => write!(f, "LDAP operation failed: {code:?}"),
108 Error::InvalidResponse => write!(f, "Invalid response"),
109 Error::InvalidFilter(e) => write!(f, "{e}"),
110 Error::ConnectionClosed => write!(f, "Connection closed"),
111 Error::GssApiError(e) => write!(f, "{e}"),
112 Error::NoSaslCredentials => write!(f, "No SASL credentials in response"),
113 }
114 }
115}