ftp_client/
status_code.rs

1//! Contains code for using and parsing FTP status codes.
2
3/// Represent a textual interpretation
4/// of a particular status code, most were
5/// taken from RFC 959.
6#[derive(Debug, PartialEq)]
7pub enum StatusCodeKind {
8    /// Status code 125
9    TransferStarted,
10    /// Status code 150
11    TransferAboutToStart,
12    /// Status code 200
13    Ok,
14    /// Status code 202
15    FeatureNotImplemented,
16    /// Status code 211,
17    SystemStatus,
18    /// Status code 214
19    HelpMessage,
20    /// Status code 215
21    NameSystemType,
22    /// Status code 220
23    ReadyForNewUser,
24    /// Status code 221
25    ClosingControlConnection,
26    /// Status code 226
27    RequestActionCompleted,
28    /// Status code 230
29    UserLoggedIn,
30    /// Status code 227
31    EnteredPassiveMode,
32    /// Status code 229
33    EnteredExtendedPassiveMode,
34    /// Status code 250
35    RequestFileActionCompleted,
36    /// Status code 257
37    PathCreated,
38    /// Status code 331
39    PasswordRequired,
40    /// Status code 350
41    RequestActionPending,
42    /// Status code 500
43    CommandUnrecognized,
44    /// Status code 504
45    SecurityMechanismNotImplemented,
46    /// Status code 550
47    RequestActionDenied,
48    /// Status code 553
49    FileNameNotAllowed,
50    /// Status code not expected by any implementation
51    /// on this crate.
52    Unknown,
53}
54
55impl From<u16> for StatusCodeKind {
56    fn from(code: u16) -> StatusCodeKind {
57        match code {
58            125 => StatusCodeKind::TransferStarted,
59            150 => StatusCodeKind::TransferAboutToStart,
60            200 => StatusCodeKind::Ok,
61            202 => StatusCodeKind::FeatureNotImplemented,
62            211 => StatusCodeKind::SystemStatus,
63            214 => StatusCodeKind::HelpMessage,
64            215 => StatusCodeKind::NameSystemType,
65            221 => StatusCodeKind::ClosingControlConnection,
66            220 => StatusCodeKind::ReadyForNewUser,
67            226 => StatusCodeKind::RequestActionCompleted,
68            227 => StatusCodeKind::EnteredPassiveMode,
69            229 => StatusCodeKind::EnteredExtendedPassiveMode,
70            230 => StatusCodeKind::UserLoggedIn,
71            250 => StatusCodeKind::RequestFileActionCompleted,
72            257 => StatusCodeKind::PathCreated,
73            331 => StatusCodeKind::PasswordRequired,
74            350 => StatusCodeKind::RequestActionPending,
75            500 => StatusCodeKind::CommandUnrecognized,
76            504 => StatusCodeKind::SecurityMechanismNotImplemented,
77            550 => StatusCodeKind::RequestActionDenied,
78            553 => StatusCodeKind::FileNameNotAllowed,
79            _ => StatusCodeKind::Unknown,
80        }
81    }
82}
83
84/// Contains a [StatusCodeKind](enum.StatusCodeKind.html) and
85/// the corresponding code for it, this is useful on generating
86/// error messages and validity of a particular code.
87#[derive(Debug)]
88pub struct StatusCode {
89    /// The [StatusCodeKind](enum.StatusCodeKind.html)
90    pub kind: StatusCodeKind,
91    /// The integer representing the status code
92    pub code: u16,
93}
94
95impl PartialEq for StatusCode {
96    fn eq(&self, other: &StatusCode) -> bool {
97        self.code == other.code
98    }
99}
100
101impl StatusCode {
102    /// Parse a server response into a [StatusCode](struct.StatusCode.html) struct.
103    pub fn parse(text: &str) -> Self {
104        let code: &u16 = &text[0..3].parse().unwrap();
105        let code: u16 = *code;
106        let kind = StatusCodeKind::from(code);
107
108        Self { kind, code }
109    }
110
111    /// Returns whether a status code number is valid.
112    pub fn is_valid(&self) -> bool {
113        self.code > 199 && self.code < 399
114    }
115
116    /// Returns whether a status code number is a failure.
117    pub fn is_failure(&self) -> bool {
118        self.code > 399 && self.code < 599
119    }
120}