ldap_rs/
error.rs

1//! LDAP errors
2
3use 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/// LDAP operation error
12#[derive(Debug)]
13pub struct OperationError {
14    /// Result code
15    pub result_code: ResultCode,
16    /// Matched DN
17    pub matched_dn: String,
18    /// Diagnostic message
19    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/// LDAP errors
43#[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}