Improved documentation for the top-level library and Message struct.

This commit is contained in:
Aaron Weiss 2017-12-24 21:23:19 -05:00
parent 6348ad0567
commit f78909f74d
No known key found for this signature in database
GPG key ID: 047D32DF25DC22EF
2 changed files with 105 additions and 3 deletions

View file

@ -1,4 +1,43 @@
//! A simple, thread-safe, and async-friendly library for IRC clients. //! A simple, thread-safe, and async-friendly library for IRC clients.
//!
//! # Quick Start
//! The main public API is entirely exported in [client::prelude](./client/prelude/index.html). This
//! should include everything necessary to write an IRC client or bot.
//!
//! # A Whirlwind Tour
//! The irc crate is divided into two main modules: [client](./client/index.html) and
//! [proto](./proto/index.html). As the names suggest, the client module captures the whole of the
//! client-side functionality, while the proto module features general components of an IRC protocol
//! implementation that could in principle be used in either client or server software. Both modules
//! feature a number of components that are low-level and can be used to build alternative APIs for
//! the IRC protocol. For the average user, the higher-level components for an IRC client are all
//! re-exported in [client::prelude](./client/prelude/index.html). That module serves as the best
//! starting point for a new user trying to understand the high-level API.
//!
//! # Example
//!
//! ```no_run
//! # extern crate irc;
//! use irc::client::prelude::*;
//!
//! # fn main() {
//! // configuration is loaded from config.toml into a Config
//! let server = IrcServer::new("config.toml").unwrap();
//! // identify comes from ServerExt
//! server.identify().unwrap();
//! // for_each_incoming comes from Server
//! server.for_each_incoming(|irc_msg| {
//! // irc_msg is a Message
//! match irc_msg.command {
//! Command::PRIVMSG(channel, message) => if message.contains(server.current_nickname()) {
//! // send_privmsg comes from ServerExt
//! server.send_privmsg(&channel, "beep boop").unwrap();
//! }
//! _ => ()
//! }
//! }).unwrap();
//! # }
//! ```
#![warn(missing_docs)] #![warn(missing_docs)]
#![recursion_limit="128"] #![recursion_limit="128"]

View file

@ -7,19 +7,37 @@ use error;
use error::{Error, ErrorKind}; use error::{Error, ErrorKind};
use proto::{Command, ChannelExt}; use proto::{Command, ChannelExt};
/// A data structure representing an IRC message according to the protocol specification. /// A data structure representing an IRC message according to the protocol specification. It
/// consists of a collection of IRCv3 tags, a prefix (describing the source of the message), and
/// the protocol command. If the command is unknown, it is treated as a special raw command that
/// consists of a collection of arguments and the special suffix argument. Otherwise, the command
/// is parsed into a more useful form as described in [Command](../command/enum.Command.html).
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Message { pub struct Message {
/// Message tags as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html). /// Message tags as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html).
/// These tags are used to add extended information to the given message, and are commonly used
/// in IRCv3 extensions to the IRC protocol.
pub tags: Option<Vec<Tag>>, pub tags: Option<Vec<Tag>>,
/// The message prefix (or source) as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812). /// The message prefix (or source) as defined by [RFC 2812](http://tools.ietf.org/html/rfc2812).
pub prefix: Option<String>, pub prefix: Option<String>,
/// The IRC command. /// The IRC command, parsed according to the known specifications. The command itself and its
/// arguments (including the special suffix argument) are captured in this component.
pub command: Command, pub command: Command,
} }
impl Message { impl Message {
/// Creates a new message from the given components. /// Creates a new message from the given components.
///
/// # Example
/// ```
/// # extern crate irc;
/// # use irc::client::prelude::*;
/// # fn main() {
/// let message = Message::new(
/// Some("nickname!username@hostname"), "JOIN", vec!["#channel"], None
/// ).unwrap();
/// # }
/// ```
pub fn new( pub fn new(
prefix: Option<&str>, prefix: Option<&str>,
command: &str, command: &str,
@ -29,7 +47,9 @@ impl Message {
Message::with_tags(None, prefix, command, args, suffix) Message::with_tags(None, prefix, command, args, suffix)
} }
/// Creates a new IRCv3.2 message from the given components, including message tags. /// Creates a new IRCv3.2 message from the given components, including message tags. These tags
/// are used to add extended information to the given message, and are commonly used in IRCv3
/// extensions to the IRC protocol.
pub fn with_tags( pub fn with_tags(
tags: Option<Vec<Tag>>, tags: Option<Vec<Tag>>,
prefix: Option<&str>, prefix: Option<&str>,
@ -45,6 +65,18 @@ impl Message {
} }
/// Gets the nickname of the message source, if it exists. /// Gets the nickname of the message source, if it exists.
///
/// # Example
/// ```
/// # extern crate irc;
/// # use irc::client::prelude::*;
/// # fn main() {
/// let message = Message::new(
/// Some("nickname!username@hostname"), "JOIN", vec!["#channel"], None
/// ).unwrap();
/// assert_eq!(message.source_nickname(), Some("nickname"));
/// # }
/// ```
pub fn source_nickname(&self) -> Option<&str> { pub fn source_nickname(&self) -> Option<&str> {
// <prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ] // <prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
// <servername> ::= <host> // <servername> ::= <host>
@ -63,6 +95,22 @@ impl Message {
/// Gets the likely intended place to respond to this message. /// Gets the likely intended place to respond to this message.
/// If the type of the message is a `PRIVMSG` or `NOTICE` and the message is sent to a channel, /// If the type of the message is a `PRIVMSG` or `NOTICE` and the message is sent to a channel,
/// the result will be that channel. In all other cases, this will call `source_nickname`. /// the result will be that channel. In all other cases, this will call `source_nickname`.
///
/// # Example
/// ```
/// # extern crate irc;
/// # use irc::client::prelude::*;
/// # fn main() {
/// let msg1 = Message::new(
/// Some("ada"), "PRIVMSG", vec!["#channel"], Some("Hi, everyone!")
/// ).unwrap();
/// assert_eq!(msg1.response_target(), Some("#channel"));
/// let msg2 = Message::new(
/// Some("ada"), "PRIVMSG", vec!["betsy"], Some("betsy: hi")
/// ).unwrap();
/// assert_eq!(msg2.response_target(), Some("ada"));
/// # }
/// ```
pub fn response_target(&self) -> Option<&str> { pub fn response_target(&self) -> Option<&str> {
match self.command { match self.command {
Command::PRIVMSG(ref target, _) if target.is_channel_name() => Some(target), Command::PRIVMSG(ref target, _) if target.is_channel_name() => Some(target),
@ -72,6 +120,18 @@ impl Message {
} }
/// Converts a Message into a String according to the IRC protocol. /// Converts a Message into a String according to the IRC protocol.
///
/// # Example
/// ```
/// # extern crate irc;
/// # use irc::client::prelude::*;
/// # fn main() {
/// let msg = Message::new(
/// Some("ada"), "PRIVMSG", vec!["#channel"], Some("Hi, everyone!")
/// ).unwrap();
/// assert_eq!(msg.to_string(), ":ada PRIVMSG #channel :Hi, everyone!\r\n");
/// # }
/// ```
pub fn to_string(&self) -> String { pub fn to_string(&self) -> String {
let mut ret = String::new(); let mut ret = String::new();
if let Some(ref tags) = self.tags { if let Some(ref tags) = self.tags {
@ -176,6 +236,9 @@ impl Display for Message {
} }
/// A message tag as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html). /// A message tag as defined by [IRCv3.2](http://ircv3.net/specs/core/message-tags-3.2.html).
/// It consists of a tag key, and an optional value for the tag. Each message can contain a number
/// of tags (in the string format, they are separated by semicolons). Tags are used to add extended
/// information to a message under IRCv3.
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub struct Tag(pub String, pub Option<String>); pub struct Tag(pub String, pub Option<String>);