From 26062171cccec44ff6ac8bf4d545b5a32a7084bc Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Sun, 21 May 2023 23:27:49 -0400 Subject: [PATCH] Initial commit --- .gitignore | 2 + Cargo.toml | 9 +++ src/lib.rs | 16 +++++ src/status.rs | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++ tags | 92 ++++++++++++++++++++++++++++ 5 files changed, 281 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 src/status.rs create mode 100644 tags diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7f6fbed --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dory" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rustls = "0.21.1" diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..84c439a --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,16 @@ +pub mod status; + +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/src/status.rs b/src/status.rs new file mode 100644 index 0000000..58a2eca --- /dev/null +++ b/src/status.rs @@ -0,0 +1,162 @@ +use std::fmt; + +#[derive(Debug, Clone, PartialEq)] +pub struct StatusError; + +impl fmt::Display for StatusError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +impl std::error::Error for StatusError {} + +#[derive(Debug, Clone, PartialEq)] +#[repr(u8)] +pub enum Status { + /// These codes are reserved, and must not be sent by a Misfin server. + Input = 10, + /// Status codes beginning with 2 are SUCCESS status codes, which mean + /// that the client's message has been delivered. + Success = 20, + /// The mailbox has moved to a different address, and this message should + /// be resent to that address. + Redirect(Redirect) = 30, + /// Status codes beginning with 5 are PERMANENT FAILURE status codes, which + /// mean the request did not succeed, and should not be retried. + TemporaryFailure(TemporaryFailure) = 40, + /// Something is wrong with the mailserver, and you should not try to + /// resend your message. + PermanentFailure(PermanentFailure) = 50, + /// Status codes beginning with 6 are AUTHENTICATION FAILURE status codes, + /// which mean that there was an issue with the client's certificate. + AuthenticationFailure(AuthenticationFailure) = 60, +} + +impl TryFrom for Status { + type Error = StatusError; + + fn try_from(value: u8) -> Result { + match value { + n if n / 10 == 1 => Ok(Self::Input), + n if n / 20 == 1 => Ok(Self::Success), + n if n / 30 == 1 => Ok(Self::Redirect((value % 30).try_into()?)), + n if n / 40 == 1 => Ok(Self::TemporaryFailure((value % 40).try_into()?)), + n if n / 50 == 1 => Ok(Self::PermanentFailure((value % 50).try_into()?)), + n if n / 60 == 1 => Ok(Self::AuthenticationFailure((value % 60).try_into()?)), + _ => Err(StatusError), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum Redirect { + /// The mailbox has moved to a different address, and this message + /// should be resent to that address. + Temporary = 0, + /// The mailbox has moved to a different address, and all future + /// messages should be sent to that address. + Permanent = 1, + Other, +} + +impl TryFrom for Redirect { + type Error = StatusError; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Self::Temporary), + 1 => Ok(Self::Permanent), + n if n < 10 => Ok(Self::Other), + _ => Err(StatusError), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum TemporaryFailure { + /// The mailserver experienced a transient issue, and the message + /// should be resent. + TemporaryError = 0, + /// The mailserver can't accept mail right now. + ServerUnavailable = 1, + /// A mailserver script ran for your message, but experienced an error. + CgiError = 2, + /// There was a problem accepting mail for that domain, but it might + /// resolve itself. + ProxyError = 3, + /// You are being rate limited - wait before trying to send more mail. + RateLimit = 4, + /// The mailbox isn't accepting mail right now, but it might in the future. + MailboxFull = 5, + Other, +} + +impl TryFrom for TemporaryFailure { + type Error = StatusError; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Self::TemporaryError), + 1 => Ok(Self::ServerUnavailable), + 2 => Ok(Self::CgiError), + 3 => Ok(Self::ProxyError), + 4 => Ok(Self::RateLimit), + 5 => Ok(Self::MailboxFull), + n if n < 10 => Ok(Self::Other), + _ => Err(StatusError), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum PermanentFailure { + PermanentError = 0, + MailboxNonexistent = 1, + MailboxGone = 2, + DomainNotServiced = 3, + BadRequest = 9, + Other, +} + +impl TryFrom for PermanentFailure { + type Error = StatusError; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Self::PermanentError), + 1 => Ok(Self::MailboxNonexistent), + 2 => Ok(Self::MailboxGone), + 3 => Ok(Self::DomainNotServiced), + 9 => Ok(Self::BadRequest), + n if n < 10 => Ok(Self::Other), + _ => Err(StatusError), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum AuthenticationFailure { + CertificateRequired = 0, + UnauthorizedSender = 1, + CertificateInvalid = 2, + IdentityMismatch = 3, + ProofRequired = 4, + Other, +} + +impl TryFrom for AuthenticationFailure { + type Error = StatusError; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Self::CertificateRequired), + 1 => Ok(Self::UnauthorizedSender), + 2 => Ok(Self::CertificateInvalid), + 3 => Ok(Self::IdentityMismatch), + 4 => Ok(Self::ProofRequired), + n if n < 10 => Ok(Self::Other), + _ => Err(StatusError), + } + } +} diff --git a/tags b/tags new file mode 100644 index 0000000..a31ed38 --- /dev/null +++ b/tags @@ -0,0 +1,92 @@ +!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/ +!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/ +!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/ +!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/ +!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/ +!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/ +!_TAG_FIELD_DESCRIPTION input /input file/ +!_TAG_FIELD_DESCRIPTION name /tag name/ +!_TAG_FIELD_DESCRIPTION pattern /pattern/ +!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_KIND_DESCRIPTION!Rust C,constant /A constant/ +!_TAG_KIND_DESCRIPTION!Rust M,macro /Macro Definition/ +!_TAG_KIND_DESCRIPTION!Rust P,method /A method/ +!_TAG_KIND_DESCRIPTION!Rust c,implementation /implementation/ +!_TAG_KIND_DESCRIPTION!Rust e,enumerator /An enum variant/ +!_TAG_KIND_DESCRIPTION!Rust f,function /Function/ +!_TAG_KIND_DESCRIPTION!Rust g,enum /Enum/ +!_TAG_KIND_DESCRIPTION!Rust i,interface /trait interface/ +!_TAG_KIND_DESCRIPTION!Rust m,field /A struct field/ +!_TAG_KIND_DESCRIPTION!Rust n,module /module/ +!_TAG_KIND_DESCRIPTION!Rust s,struct /structural type/ +!_TAG_KIND_DESCRIPTION!Rust t,typedef /Type Alias/ +!_TAG_KIND_DESCRIPTION!Rust v,variable /Global variable/ +!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/ +!_TAG_OUTPUT_FILESEP slash /slash or backslash/ +!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ +!_TAG_OUTPUT_VERSION 0.0 /current.age/ +!_TAG_PARSER_VERSION!Rust 0.0 /current.age/ +!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/ +!_TAG_PROC_CWD /home/nathan/src/dory/ // +!_TAG_PROGRAM_AUTHOR Universal Ctags Team // +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +!_TAG_PROGRAM_URL https://ctags.io/ /official site/ +!_TAG_PROGRAM_VERSION 6.0.0 /p6.0.20221218.0/ +AuthenticationFailure src/status.rs /^ AuthenticationFailure(AuthenticationFailure) = 60,$/;" e enum:Status +AuthenticationFailure src/status.rs /^impl TryFrom for AuthenticationFailure {$/;" c +AuthenticationFailure src/status.rs /^pub enum AuthenticationFailure {$/;" g +BadRequest src/status.rs /^ BadRequest = 9,$/;" e enum:PermanentFailure +CertificateInvalid src/status.rs /^ CertificateInvalid = 2,$/;" e enum:AuthenticationFailure +CertificateRequired src/status.rs /^ CertificateRequired = 0,$/;" e enum:AuthenticationFailure +CgiError src/status.rs /^ CgiError = 2,$/;" e enum:TemporaryFailure +DomainNotServiced src/status.rs /^ DomainNotServiced = 3,$/;" e enum:PermanentFailure +Error src/status.rs /^ type Error = StatusError;$/;" t implementation:AuthenticationFailure +Error src/status.rs /^ type Error = StatusError;$/;" t implementation:PermanentFailure +Error src/status.rs /^ type Error = StatusError;$/;" t implementation:Redirect +Error src/status.rs /^ type Error = StatusError;$/;" t implementation:Status +Error src/status.rs /^ type Error = StatusError;$/;" t implementation:TemporaryFailure +IdentityMismatch src/status.rs /^ IdentityMismatch = 3,$/;" e enum:AuthenticationFailure +Input src/status.rs /^ Input = 10,$/;" e enum:Status +MailboxFull src/status.rs /^ MailboxFull = 5,$/;" e enum:TemporaryFailure +MailboxGone src/status.rs /^ MailboxGone = 2,$/;" e enum:PermanentFailure +MailboxNonexistent src/status.rs /^ MailboxNonexistent = 1,$/;" e enum:PermanentFailure +Other src/status.rs /^ Other,$/;" e enum:AuthenticationFailure +Other src/status.rs /^ Other,$/;" e enum:PermanentFailure +Other src/status.rs /^ Other,$/;" e enum:Redirect +Other src/status.rs /^ Other,$/;" e enum:TemporaryFailure +Permanent src/status.rs /^ Permanent = 1,$/;" e enum:Redirect +PermanentError src/status.rs /^ PermanentError = 0,$/;" e enum:PermanentFailure +PermanentFailure src/status.rs /^ PermanentFailure(PermanentFailure) = 50,$/;" e enum:Status +PermanentFailure src/status.rs /^impl TryFrom for PermanentFailure {$/;" c +PermanentFailure src/status.rs /^pub enum PermanentFailure {$/;" g +ProofRequired src/status.rs /^ ProofRequired = 4,$/;" e enum:AuthenticationFailure +ProxyError src/status.rs /^ ProxyError = 3,$/;" e enum:TemporaryFailure +RateLimit src/status.rs /^ RateLimit = 4,$/;" e enum:TemporaryFailure +Redirect src/status.rs /^ Redirect(Redirect) = 30,$/;" e enum:Status +Redirect src/status.rs /^impl TryFrom for Redirect {$/;" c +Redirect src/status.rs /^pub enum Redirect {$/;" g +ServerUnavailable src/status.rs /^ ServerUnavailable = 1,$/;" e enum:TemporaryFailure +Status src/status.rs /^impl TryFrom for Status {$/;" c +Status src/status.rs /^pub enum Status {$/;" g +StatusError src/status.rs /^impl fmt::Display for StatusError {$/;" c +StatusError src/status.rs /^impl std::error::Error for StatusError {}$/;" c +StatusError src/status.rs /^pub struct StatusError;$/;" s +Success src/status.rs /^ Success = 20,$/;" e enum:Status +Temporary src/status.rs /^ Temporary = 0,$/;" e enum:Redirect +TemporaryError src/status.rs /^ TemporaryError = 0,$/;" e enum:TemporaryFailure +TemporaryFailure src/status.rs /^ TemporaryFailure(TemporaryFailure) = 40,$/;" e enum:Status +TemporaryFailure src/status.rs /^impl TryFrom for TemporaryFailure {$/;" c +TemporaryFailure src/status.rs /^pub enum TemporaryFailure {$/;" g +UnauthorizedSender src/status.rs /^ UnauthorizedSender = 1,$/;" e enum:AuthenticationFailure +add src/lib.rs /^pub fn add(left: usize, right: usize) -> usize {$/;" f +fmt src/status.rs /^ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {$/;" P implementation:StatusError +it_works src/lib.rs /^ fn it_works() {$/;" f module:tests +status src/lib.rs /^pub mod status;$/;" n +tests src/lib.rs /^mod tests {$/;" n +try_from src/status.rs /^ fn try_from(value: u8) -> Result {$/;" P implementation:AuthenticationFailure +try_from src/status.rs /^ fn try_from(value: u8) -> Result {$/;" P implementation:PermanentFailure +try_from src/status.rs /^ fn try_from(value: u8) -> Result {$/;" P implementation:Redirect +try_from src/status.rs /^ fn try_from(value: u8) -> Result {$/;" P implementation:Status +try_from src/status.rs /^ fn try_from(value: u8) -> Result {$/;" P implementation:TemporaryFailure