🏡 index : ~doyle/titanirc.git

author Jordan Doyle <jordan@doyle.la> 2021-02-01 1:55:55.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-02-01 1:55:55.0 +00:00:00
commit
fe905274cdfc6b7071e166e1edf2948c3734d25d [patch]
tree
f112f7210b8a5a31b6aa7c6ad3c95b51d5025e53
parent
c7813bb5ae43dea7ab73cd4abfa1efce20f77ecb
download
fe905274cdfc6b7071e166e1edf2948c3734d25d.tar.gz

Add some docs for titanirc_types



Diff

 titanirc-types/src/lib.rs        | 20 ++++++++++++++------
 titanirc-types/src/primitives.rs |  2 ++
 titanirc-types/src/replies.rs    | 19 +++++++++++++++++++
 3 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/titanirc-types/src/lib.rs b/titanirc-types/src/lib.rs
index 044d762..ad5b569 100644
--- a/titanirc-types/src/lib.rs
+++ b/titanirc-types/src/lib.rs
@@ -29,6 +29,9 @@ macro_rules! define_commands {
        ),* $(,)?
    ) => {
        paste::paste! {
            /// All the commands that can be ran by a client, also provides a `Display`
            /// implementation that serialises the command for sending over the wire,
            /// ie. for forwarding.
            #[derive(Debug)]
            pub enum Command<'a> {
                $([<$name:camel>]([<$name:camel Command>]<'a>)),*
@@ -37,15 +40,16 @@ macro_rules! define_commands {
            $(const [<$name _BYTES>]: &[u8] = stringify!($name).as_bytes();)*

            impl Command<'_> {
                /// Parses a command from the wire, returning an `Err` if the command was unparsable or
                /// `Ok(None)` if the command was unrecognsied. The given `Bytes` should have the CRLF
                /// stripped.
                pub fn parse(input: Bytes) -> Result<Option<Self>, nom::Err<NomError<BytesWrapper>>> {
                    let input = BytesWrapper::from(input);
                    let mut input = BytesWrapper::from(input);

                    // skip the optional source at the start of the message
                    let input = if let Ok((input, _)) = parse_optional_source(input.clone()) {
                        input
                    } else {
                        input
                    };
                    if let Ok((input_source_stripped, _)) = parse_optional_source(input.clone()) {
                        input = input_source_stripped;
                    }

                    let (params, command) = take_till(|c| c == b' ')(input)?;

@@ -56,6 +60,7 @@ macro_rules! define_commands {
                }
            }

            /// Serialises the command for sending over the wire.
            impl std::fmt::Display for Command<'_> {
                fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                    match self {
@@ -72,6 +77,7 @@ macro_rules! define_commands {
                }

                impl [<$name:camel Command>]<'_> {
                    /// Parses the command's arguments, with each parameter separated by a space.
                    #[allow(unused_variables)]
                    pub fn parse(rest: BytesWrapper) -> Result<Self, nom::Err<nom::error::Error<BytesWrapper>>> {
                        $(
@@ -88,6 +94,8 @@ macro_rules! define_commands {
                    }
                }

                /// Serialises the command's arguments for sending over the wire, joining
                /// all the arguments separating them with a space.
                impl std::fmt::Display for [<$name:camel Command>]<'_> {
                    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                        fmt.write_str(stringify!($name))?;
diff --git a/titanirc-types/src/primitives.rs b/titanirc-types/src/primitives.rs
index e4f9341..40490d1 100644
--- a/titanirc-types/src/primitives.rs
+++ b/titanirc-types/src/primitives.rs
@@ -18,6 +18,8 @@ pub trait PrimitiveParser {
        Self: Sized;
}

/// A `Cow`-like implementation where `Owned` is a `bytes::Bytes` and `Borrowed`
/// is `&[u8]`.
#[derive(Debug, From)]
pub enum BytesCow<'a> {
    Owned(Bytes),
diff --git a/titanirc-types/src/replies.rs b/titanirc-types/src/replies.rs
index e680b67..b11eb08 100644
--- a/titanirc-types/src/replies.rs
+++ b/titanirc-types/src/replies.rs
@@ -3,21 +3,37 @@
use crate::{primitives::*, Command};
use std::fmt::Write;

/// The origin of a message that's about to be returned to the client.
#[derive(Debug)]
pub enum Source<'a> {
    User(Nick<'a>), // change Nick to whatever type nick!user@netmask is..
    Server,
}

impl<'a> From<Nick<'a>> for Source<'a> {
    fn from(other: Nick<'a>) -> Self {
        Self::User(other)
    }
}

/// A message to be sent to the client over the wire.
#[derive(Debug, derive_more::From)]
pub enum ServerMessage<'a> {
    /// A `RPL_*`/`ERR_*` type from the IRC spec.
    Reply(Reply<'a>),
    /// Normally a 'forwarded' message, ie. a `VERSION` for another client or
    /// a `PRIVMSG`.
    Command(Source<'a>, Command<'a>), // change Nick to whatever type nick!user@netmask is..
    /// A server ping to the client.
    Ping,
    /// A server pong to the client.
    Pong,
}

impl ServerMessage<'_> {
    /// Writes out this `ServerMessage` to `dst`, in the expected format for the wire.
    ///
    /// This function omits the CRLF from the end of the line.
    pub fn write(self, server_name: &str, client_username: &str, dst: &mut bytes::BytesMut) {
        match self {
            Self::Reply(reply) => write!(
@@ -48,6 +64,7 @@ macro_rules! define_replies {
            $name:ident$(($($arg:ident$(<$($gen:tt),+>)?),*))? = $num:expr $(=> $msg:expr)?
        ),* $(,)?
    ) => {
        /// A `RPL_*` or `ERR_*` type as defined in the IRC spec.
        #[derive(Debug)]
        #[allow(clippy::pub_enum_variant_names)]
        pub enum Reply<'a> {
@@ -56,6 +73,7 @@ macro_rules! define_replies {
            )*
        }

        /// Outputs the `RPL_*`/`ERR_*` type for the wire as defined in the IRC spec.
        impl std::fmt::Display for Reply<'_> {
            fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                paste::paste! {
@@ -67,6 +85,7 @@ macro_rules! define_replies {
        }

        impl Reply<'_> {
            /// The numeric code for this reply kind.
            #[must_use]
            pub fn code(&self) -> &'static str {
                paste::paste! {