commit
2440a751d9
8 changed files with 399 additions and 240 deletions
|
@ -1,16 +1,13 @@
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- secure: aGzqk53//ZQmZ/7Eb8XtlUG3bmwmR5p+RCSqUEz0xUazsYAO0/NRYgEkebXpggvjQCaJFsWWNxfSq5+3bVa43boIChKzshkrqIvF6sO5RxMslNQbb4rabo4GadJYMMFmoG/3h1EwFk3pEsAorNC/M6VVuH9XLKD5dWgvefMqclc=
|
|
||||||
language: rust
|
language: rust
|
||||||
rust: stable
|
rust: stable
|
||||||
sudo: false
|
sudo: false
|
||||||
script:
|
script:
|
||||||
- chmod +x mktestconfig.sh
|
- chmod +x mktestconfig.sh
|
||||||
- ./mktestconfig.sh
|
- ./mktestconfig.sh
|
||||||
- cargo build --verbose --features "toml yaml"
|
- cargo build --verbose
|
||||||
|
- rustdoc --test README.md --extern irc=target/debug/libirc.rlib -L target/debug/deps
|
||||||
- cargo test --verbose --features "toml yaml"
|
- cargo test --verbose --features "toml yaml"
|
||||||
- cargo test --doc
|
- cargo test --doc
|
||||||
- cargo build --verbose --no-default-features
|
|
||||||
- cargo test --verbose --no-default-features
|
- cargo test --verbose --no-default-features
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|
46
CONTRIBUTING.md
Normal file
46
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# How to contribute
|
||||||
|
|
||||||
|
Your contributions are essential for making the irc crate the best piece of software it could
|
||||||
|
possibly be! We welcome contributions from programmers of all skill levels, and are happy to provide
|
||||||
|
mentorship for new contributors working on bug fixes. To make the onboarding process as painless as
|
||||||
|
possible for everyone, there are a few guidelines that we need contributors to follow.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
* Make sure you have a [GitHub account](https://github.com/signup/free).
|
||||||
|
* Fork the repository on GitHub.
|
||||||
|
|
||||||
|
## Making Changes
|
||||||
|
|
||||||
|
* Create a topic branch from where you want to base your work.
|
||||||
|
* This is almost always the develop branch.
|
||||||
|
* Only target stable or a maintainer's feature branch if you are certain your fix must be on that
|
||||||
|
branch.
|
||||||
|
* To quickly create a topic branch based on develop, run `git checkout -b
|
||||||
|
fix/develop/my_contribution develop`. Please avoid working directly on the
|
||||||
|
`stable` branch, and keep direct work on `develop` minor.
|
||||||
|
* Make commits of logical and atomic units.
|
||||||
|
* Check for unnecessary whitespace with `git diff --check` before committing.
|
||||||
|
* Make sure you have added the necessary tests for your changes.
|
||||||
|
* Run _all_ the tests to assure nothing else was accidentally broken using `cargo test`. You can
|
||||||
|
also run `cargo test --no-default-features`, but this is generally not relevant and will be
|
||||||
|
handled by our continuous integration tools.
|
||||||
|
* Some tests related to configurations will fail if you don't run the `mktestconfig.sh` script.
|
||||||
|
|
||||||
|
## Submitting Changes
|
||||||
|
|
||||||
|
* Push your changes to a topic branch in your fork of the repository.
|
||||||
|
* Submit a pull request to the `aatxe/irc` repository.
|
||||||
|
* Await maintainer feedback and continuous integration results.
|
||||||
|
* We make an effort to triage quickly, but patience is appreciated!
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
* [Code of Conduct](https://github.com/aatxe/irc/blob/develop/CODE_OF_CONDUCT.md)
|
||||||
|
* [the irc crate docs](https://docs.rs/irc)
|
||||||
|
* #rust-irc IRC channel on irc.mozilla.org
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
These contributing guidelines were inspired by the
|
||||||
|
[Puppet contributor guidelines](https://github.com/puppetlabs/puppet/blob/master/CONTRIBUTING.md).
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "irc"
|
name = "irc"
|
||||||
version = "0.13.2"
|
version = "0.13.3"
|
||||||
description = "A simple, thread-safe, and async-friendly library for IRC clients."
|
description = "A simple, thread-safe, and async-friendly library for IRC clients."
|
||||||
authors = ["Aaron Weiss <awe@pdgn.co>"]
|
authors = ["Aaron Weiss <awe@pdgn.co>"]
|
||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
|
|
160
README.md
160
README.md
|
@ -1,4 +1,4 @@
|
||||||
# irc [![Build Status][ci-badge]][ci] [![Crates.io][cr-badge]][cr] [![Docs][doc-badge]][doc] [![Built with Spacemacs][bws]][sm]
|
# the irc crate [![Build Status][ci-badge]][ci] [![Crates.io][cr-badge]][cr] [![Docs][doc-badge]][doc] [![Built with Spacemacs][bws]][sm]
|
||||||
|
|
||||||
[ci-badge]: https://travis-ci.org/aatxe/irc.svg?branch=stable
|
[ci-badge]: https://travis-ci.org/aatxe/irc.svg?branch=stable
|
||||||
[ci]: https://travis-ci.org/aatxe/irc
|
[ci]: https://travis-ci.org/aatxe/irc
|
||||||
|
@ -9,78 +9,123 @@
|
||||||
[bws]: https://cdn.rawgit.com/syl20bnr/spacemacs/442d025779da2f62fc86c2082703697714db6514/assets/spacemacs-badge.svg
|
[bws]: https://cdn.rawgit.com/syl20bnr/spacemacs/442d025779da2f62fc86c2082703697714db6514/assets/spacemacs-badge.svg
|
||||||
[sm]: http://spacemacs.org
|
[sm]: http://spacemacs.org
|
||||||
|
|
||||||
A robust, thread-safe and async-friendly library for IRC clients in Rust. It's compliant with
|
[rfc2812]: http://tools.ietf.org/html/rfc2812
|
||||||
[RFC 2812](http://tools.ietf.org/html/rfc2812), [IRCv3.1](http://ircv3.net/irc/3.1.html),
|
[ircv3.1]: http://ircv3.net/irc/3.1.html
|
||||||
[IRCv3.2](http://ircv3.net/irc/3.2.html), and includes some additional, common features. It also
|
[ircv3.2]: http://ircv3.net/irc/3.2.html
|
||||||
includes a number of useful built-in features to faciliate rapid development of clients. You can
|
|
||||||
find up-to-date, ready-to-use documentation online [here](https://docs.rs/irc/). The
|
"the irc crate" is a thread-safe and async-friendly IRC client library written in Rust. It's
|
||||||
documentation is generated with the default features. These are, however, strictly optional and
|
compliant with [RFC 2812][rfc2812], [IRCv3.1][ircv3.1], [IRCv3.2][ircv3.2], and includes some
|
||||||
can be disabled accordingly.
|
additional, common features from popular IRCds. You can find up-to-date, ready-to-use documentation
|
||||||
|
online [on docs.rs][doc].
|
||||||
|
|
||||||
|
## Built with the irc crate ##
|
||||||
|
|
||||||
|
the irc crate is being used to build new IRC software in Rust. Here are some of our favorite
|
||||||
|
projects:
|
||||||
|
|
||||||
|
- [alectro][alectro] — a terminal IRC client
|
||||||
|
- [spilo][spilo] — a minimalistic IRC bouncer
|
||||||
|
- [irc-bot.rs][ircbot] — a library for writing IRC bots
|
||||||
|
- [bunnybutt-rs][bunnybutt] — an IRC bot for the [Feed The Beast Wiki][ftb-wiki]
|
||||||
|
|
||||||
|
[alectro]: https://github.com/aatxe/alectro
|
||||||
|
[spilo]: https://github.com/aatxe/spilo
|
||||||
|
[ircbot]: https://github.com/8573/irc-bot.rs
|
||||||
|
[bunnybutt]: https://github.com/FTB-Gamepedia/bunnybutt-rs
|
||||||
|
[ftb-wiki]: https://ftb.gamepedia.com/FTB_Wiki
|
||||||
|
|
||||||
|
Making your own project? [Submit a pull request](https://github.com/aatxe/irc/pulls) to add it!
|
||||||
|
|
||||||
## Getting Started ##
|
## Getting Started ##
|
||||||
|
|
||||||
To start using this library with cargo, you can simply add `irc = "0.13"` to your dependencies in
|
To start using the irc crate with cargo, you can simply add `irc = "0.13"` to your dependencies in
|
||||||
your Cargo.toml file. You'll likely want to take a look at some of the examples, as well as the
|
your Cargo.toml file. The high-level API can be found `irc::client::prelude` linked to from the
|
||||||
documentation. You'll also be able to find below a small template to get a feel for the library.
|
[doc root][doc]. You'll find a number of examples in `examples/`, throughout the documentation, and
|
||||||
|
below.
|
||||||
|
|
||||||
## Getting Started by Example ##
|
## A Tale of Two APIs ##
|
||||||
|
|
||||||
```rust
|
### Reactors (The "New" API) ###
|
||||||
|
|
||||||
|
The release of v0.13 brought with it a new API called `IrcReactor` that enables easier multiserver
|
||||||
|
support and more graceful error handling. The general model is that you use the reactor to create
|
||||||
|
new `IrcClients`, register message handler functions, and finally block the thread to run the
|
||||||
|
clients with their respective handlers. Here's an example:
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
extern crate irc;
|
||||||
|
|
||||||
|
use irc::client::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// We can also load the Config at runtime via Config::load("path/to/config.toml")
|
||||||
|
let config = Config {
|
||||||
|
nickname: Some("the-irc-crate".to_owned()),
|
||||||
|
server: Some("irc.pdgn.co".to_owned()),
|
||||||
|
channels: Some(vec!["#test".to_owned()]),
|
||||||
|
..Config::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut reactor = IrcReactor::new().unwrap();
|
||||||
|
let client = reactor.prepare_client_and_connect(&config).unwrap();
|
||||||
|
client.identify().unwrap();
|
||||||
|
|
||||||
|
reactor.register_client_with_handler(client, |client, message| {
|
||||||
|
print!("{}", message);
|
||||||
|
// And here we can do whatever we want with the messages.
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
reactor.run().unwrap();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Direct Style (The "Old" API) ###
|
||||||
|
|
||||||
|
The old API for connecting to an IRC server is still supported through the `IrcClient` type. It's
|
||||||
|
simpler for the most basic use case, but will panic upon encountering any sort of connection issues.
|
||||||
|
In general, it's recommended that users switch to the new API if possible. Nevertheless, here is an
|
||||||
|
example:
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
extern crate irc;
|
extern crate irc;
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use irc::client::prelude::*;
|
use irc::client::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// We can also load the Config at runtime via Config::load("path/to/config.toml")
|
||||||
let cfg = Config {
|
let cfg = Config {
|
||||||
nickname: Some(format!("irc-rs")),
|
nickname: Some(format!("the-irc-crate")),
|
||||||
client: Some(format!("irc.example.com")),
|
server: Some(format!("irc.example.com")),
|
||||||
channels: Some(vec![format!("#test")]),
|
channels: Some(vec![format!("#test")]),
|
||||||
.. Default::default()
|
.. Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let client = IrcClient::from_config(cfg).unwrap();
|
let client = IrcClient::from_config(cfg).unwrap();
|
||||||
client.identify().unwrap();
|
client.identify().unwrap();
|
||||||
|
|
||||||
client.for_each_incoming(|message| {
|
client.for_each_incoming(|message| {
|
||||||
// Do message processing.
|
print!("{}", message);
|
||||||
|
// And here we can do whatever we want with the messages.
|
||||||
}).unwrap()
|
}).unwrap()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
It may not seem like much, but all it takes to get started with an IRC connection is the stub
|
## Configuring IRC Clients ##
|
||||||
above. In just a few lines, you can be connected to a server and processing IRC messages as you
|
|
||||||
wish. The library is built with flexibility in mind. If you need to work on multiple threads,
|
|
||||||
simply clone the server and have at it. We'll take care of the rest.
|
|
||||||
|
|
||||||
You'll probably find that programmatic configuration is a bit of a chore, and you'll often want to
|
As seen above, there are two techniques for configuring the irc crate: runtime loading and
|
||||||
be able to change the configuration between runs of the program (for example, to change the server
|
programmatic configuration. Runtime loading is done via the function `Config::load`, and is likely
|
||||||
that you're connecting to). Fortunately, runtime configuration loading is straightforward.
|
sufficient for most IRC bots. Programmatic configuration is convenient for writing tests, but can
|
||||||
|
also be useful when defining your own custom configuration format that can be converted to `Config`.
|
||||||
|
The primary configuration format is TOML, but if you are so inclined, you can use JSON and/or YAML
|
||||||
|
via the optional `json` and `yaml` features respectively. At the minimum, a configuration requires
|
||||||
|
`nickname` and `server` to be defined, and all other fields are optional. You can find detailed
|
||||||
|
explanations of the various fields on
|
||||||
|
[docs.rs](https://docs.rs/irc/0.13.2/irc/client/data/config/struct.Config.html#fields).
|
||||||
|
|
||||||
```rust
|
Alternatively, you can look at the example below of a TOML configuration with all the fields:
|
||||||
extern crate irc;
|
|
||||||
|
|
||||||
use irc::client::prelude::*;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let client = IrcClient::new("config.toml").unwrap();
|
|
||||||
client.identify().unwrap();
|
|
||||||
client.for_each_incoming(|message| {
|
|
||||||
// Do message processing.
|
|
||||||
}).unwrap()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration ##
|
|
||||||
|
|
||||||
Like the rest of the IRC crate, configuration is built with flexibility in mind. You can easily
|
|
||||||
create `Config` objects programmatically and choose your own methods for handling any saving or
|
|
||||||
loading of configuration required. However, for convenience, we've also included the option of
|
|
||||||
loading files with `serde` to write configurations. The default configuration format is TOML,
|
|
||||||
though there is optional support for JSON and YAML via the optional `json` and `yaml` features. All
|
|
||||||
the configuration fields are optional, and can thus be omitted, but a working configuration requires
|
|
||||||
at least a `server` and `nickname`. You can find detailed explanations of the configuration format
|
|
||||||
[here](https://docs.rs/irc/0.12.8/irc/client/data/config/struct.Config.html#fields).
|
|
||||||
|
|
||||||
Here's an example of a complete configuration in TOML:
|
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
owners = []
|
owners = []
|
||||||
|
@ -97,7 +142,7 @@ cert_path = "cert.der"
|
||||||
encoding = "UTF-8"
|
encoding = "UTF-8"
|
||||||
channels = ["#rust", "#haskell", "#fake"]
|
channels = ["#rust", "#haskell", "#fake"]
|
||||||
umodes = "+RB-x"
|
umodes = "+RB-x"
|
||||||
user_info = "I'm a test user for the Rust IRC crate."
|
user_info = "I'm a test user for the irc crate."
|
||||||
version = "irc:git:Rust"
|
version = "irc:git:Rust"
|
||||||
source = "https://github.com/aatxe/irc"
|
source = "https://github.com/aatxe/irc"
|
||||||
ping_time = 180
|
ping_time = 180
|
||||||
|
@ -118,7 +163,7 @@ key = "value"
|
||||||
|
|
||||||
You can convert between different configuration formats with `convertconf` like so:
|
You can convert between different configuration formats with `convertconf` like so:
|
||||||
|
|
||||||
```
|
```shell
|
||||||
cargo run --example convertconf -- -i client_config.json -o client_config.toml
|
cargo run --example convertconf -- -i client_config.json -o client_config.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -126,7 +171,12 @@ Note that the formats are automatically determined based on the selected file ex
|
||||||
tool should make it easy for users to migrate their old configurations to TOML.
|
tool should make it easy for users to migrate their old configurations to TOML.
|
||||||
|
|
||||||
## Contributing ##
|
## Contributing ##
|
||||||
Contributions to this library would be immensely appreciated. Prior to version 0.12.0, this
|
the irc crate is a free, open source library that relies on contributions from its maintainers,
|
||||||
library was public domain. As of 0.12.0, this library is offered under the Mozilla Public License
|
Aaron Weiss ([@aatxe][awe]) and Peter Atashian ([@retep998][bun]), as well as the broader Rust
|
||||||
2.0 whose text can be found in `LICENSE.md`. Fostering an inclusive community around `irc` is
|
community. It's licensed under the Mozilla Public License 2.0 whose text can be found in
|
||||||
important, and to that end, we've adopted an explicit Code of Conduct found in `CODE_OF_CONDUCT.md`.
|
`LICENSE.md`. To foster an inclusive community around the irc crate, we have adopted a Code of
|
||||||
|
Conduct whose text can be found in `CODE_OF_CONDUCT.md`. You can find details about how to
|
||||||
|
contribute in `CONTRIBUTING.md`.
|
||||||
|
|
||||||
|
[awe]: https://github.com/aatxe/
|
||||||
|
[bun]: https://github.com/retep998/
|
||||||
|
|
|
@ -398,7 +398,7 @@ impl ClientState {
|
||||||
let alt_nicks = self.config().alternate_nicknames();
|
let alt_nicks = self.config().alternate_nicknames();
|
||||||
let mut index = self.alt_nick_index.write().unwrap();
|
let mut index = self.alt_nick_index.write().unwrap();
|
||||||
if *index >= alt_nicks.len() {
|
if *index >= alt_nicks.len() {
|
||||||
panic!("All specified nicknames were in use or disallowed.")
|
return Err(error::IrcError::NoUsableNick);
|
||||||
} else {
|
} else {
|
||||||
self.send(NICK(alt_nicks[*index].to_owned()))?;
|
self.send(NICK(alt_nicks[*index].to_owned()))?;
|
||||||
*index += 1;
|
*index += 1;
|
||||||
|
@ -861,6 +861,7 @@ mod test {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use super::{IrcClient, Client};
|
use super::{IrcClient, Client};
|
||||||
|
use error::IrcError;
|
||||||
use client::data::Config;
|
use client::data::Config;
|
||||||
#[cfg(not(feature = "nochanlists"))]
|
#[cfg(not(feature = "nochanlists"))]
|
||||||
use client::data::User;
|
use client::data::User;
|
||||||
|
@ -1044,7 +1045,6 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "All specified nicknames were in use or disallowed.")]
|
|
||||||
fn ran_out_of_nicknames() {
|
fn ran_out_of_nicknames() {
|
||||||
let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\
|
let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\
|
||||||
:irc.pdgn.co 433 * test2 :Nickname is already in use.\r\n";
|
:irc.pdgn.co 433 * test2 :Nickname is already in use.\r\n";
|
||||||
|
@ -1052,9 +1052,15 @@ mod test {
|
||||||
mock_initial_value: Some(value.to_owned()),
|
mock_initial_value: Some(value.to_owned()),
|
||||||
..test_config()
|
..test_config()
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
client.for_each_incoming(|message| {
|
let res = client.for_each_incoming(|message| {
|
||||||
println!("{:?}", message);
|
println!("{:?}", message);
|
||||||
}).unwrap();
|
});
|
||||||
|
|
||||||
|
if let Err(IrcError::NoUsableNick) = res {
|
||||||
|
()
|
||||||
|
} else {
|
||||||
|
panic!("expected error when no valid nicks were specified")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -108,13 +108,10 @@ where
|
||||||
}
|
}
|
||||||
(Async::Ready(None), _) => Ok(Async::Ready(None)),
|
(Async::Ready(None), _) => Ok(Async::Ready(None)),
|
||||||
(Async::Ready(Some(msg)), _) => {
|
(Async::Ready(Some(msg)), _) => {
|
||||||
match timer_poll {
|
if let Async::Ready(msg) = timer_poll {
|
||||||
Async::Ready(msg) => {
|
|
||||||
assert!(msg.is_some());
|
assert!(msg.is_some());
|
||||||
self.send_ping()?;
|
self.send_ping()?;
|
||||||
}
|
}
|
||||||
Async::NotReady => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
match msg.command {
|
match msg.command {
|
||||||
// Automatically respond to PINGs from the server.
|
// Automatically respond to PINGs from the server.
|
||||||
|
@ -182,6 +179,13 @@ where
|
||||||
self.close()?;
|
self.close()?;
|
||||||
Err(error::IrcError::PingTimeout)
|
Err(error::IrcError::PingTimeout)
|
||||||
} else {
|
} else {
|
||||||
|
// If it's time to send a ping, we should do it! This is necessary to ensure that the
|
||||||
|
// sink half will close even if the stream half closed without a ping timeout.
|
||||||
|
if let Async::Ready(msg) = self.ping_timer.poll()? {
|
||||||
|
assert!(msg.is_some());
|
||||||
|
self.send_ping()?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(self.inner.poll_complete()?)
|
Ok(self.inner.poll_complete()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,10 @@ pub enum IrcError {
|
||||||
/// The data that failed to encode or decode.
|
/// The data that failed to encode or decode.
|
||||||
data: String,
|
data: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// All specified nicknames were in use or unusable.
|
||||||
|
#[fail(display = "none of the specified nicknames were usable")]
|
||||||
|
NoUsableNick
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Errors that occur when parsing messages.
|
/// Errors that occur when parsing messages.
|
||||||
|
|
|
@ -3,14 +3,16 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
macro_rules! make_response {
|
macro_rules! make_response {
|
||||||
($(#[$attr:meta] $variant:ident = $value:expr),+) => {
|
($($(#[$attr:meta])+ $variant:ident = $value:expr),+) => {
|
||||||
/// List of all server responses as defined in
|
/// List of all server responses as defined in
|
||||||
/// [RFC 2812](http://tools.ietf.org/html/rfc2812).
|
/// [RFC 2812](http://tools.ietf.org/html/rfc2812) and
|
||||||
/// All commands are documented with their expected form from the RFC.
|
/// [Modern docs](https://modern.ircdocs.horse/#numerics) (henceforth referred to as
|
||||||
|
/// Modern). All commands are documented with their expected form from the RFC, and any
|
||||||
|
/// useful, additional information about the response code.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
#[repr(u16)]
|
#[repr(u16)]
|
||||||
pub enum Response {
|
pub enum Response {
|
||||||
$(#[$attr] $variant = $value),+
|
$($(#[$attr])+ $variant = $value),+
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl Response {
|
||||||
|
@ -27,339 +29,389 @@ macro_rules! make_response {
|
||||||
|
|
||||||
make_response! {
|
make_response! {
|
||||||
// Expected replies
|
// Expected replies
|
||||||
/// `001 Welcome to the Internet Relay Network <nick>!<user>@<host>`
|
/// `001 Welcome to the Internet Relay Network <nick>!<user>@<host>` (Source: RFC2812)
|
||||||
RPL_WELCOME = 1,
|
RPL_WELCOME = 1,
|
||||||
/// `002 Your host is <servername>, running version <ver>`
|
/// `002 Your host is <servername>, running version <ver>` (Source: RFC2812)
|
||||||
RPL_YOURHOST = 2,
|
RPL_YOURHOST = 2,
|
||||||
/// `003 This server was created <date>`
|
/// `003 This server was created <date>` (Source: RFC2812)
|
||||||
RPL_CREATED = 3,
|
RPL_CREATED = 3,
|
||||||
/// `004 <servername> <version> <available user modes> available channel modes>`
|
/// `004 <servername> <version> <available user modes> <available channel modes>` (Source:
|
||||||
|
/// RFC2812)
|
||||||
|
///
|
||||||
|
/// Various IRCds may choose to include additional arguments to `RPL_MYINFO`, and it's best to
|
||||||
|
/// check for certain what the servers you're targeting do. Typically, there are additional
|
||||||
|
/// parameters at the end for modes that have parameters, and server modes.
|
||||||
RPL_MYINFO = 4,
|
RPL_MYINFO = 4,
|
||||||
/// `005 <servername> *(<feature>(=<value>)) :are supported by this server`
|
/// `005 <servername> *(<feature>(=<value>)) :are supported by this server` (Source: Modern)
|
||||||
|
///
|
||||||
|
/// [RPL_ISUPPORT](https://modern.ircdocs.horse/#rplisupport-005) replaces RPL_BOUNCE from
|
||||||
|
/// RFC2812, but does so consistently in modern IRCd implementations. RPL_BOUNCE has been moved
|
||||||
|
/// to `010`.
|
||||||
RPL_ISUPPORT = 5,
|
RPL_ISUPPORT = 5,
|
||||||
/// `010 Try server <server name>, port <port number>`
|
/// `010 Try server <server name>, port <port number>` (Source: Modern)
|
||||||
RPL_BOUNCE = 10,
|
RPL_BOUNCE = 10,
|
||||||
/// `302 :*1<reply> *( " " <reply> )`
|
/// Undefined format. (Source: Modern)
|
||||||
|
///
|
||||||
|
/// RPL_NONE is a dummy numeric. It does not have a defined use nor format.
|
||||||
|
RPL_NONE = 300,
|
||||||
|
/// `302 :*1<reply> *( " " <reply> )` (Source: RFC2812)
|
||||||
RPL_USERHOST = 302,
|
RPL_USERHOST = 302,
|
||||||
/// `303 :*1<nick> *( " " <nick> )`
|
/// `303 :*1<nick> *( " " <nick> )` (Source: RFC2812)
|
||||||
RPL_ISON = 303,
|
RPL_ISON = 303,
|
||||||
/// `301 <nick> :<away message>`
|
/// `301 <nick> :<away message>` (Source: RFC2812)
|
||||||
RPL_AWAY = 301,
|
RPL_AWAY = 301,
|
||||||
/// `305 :You are no longer marked as being away`
|
/// `305 :You are no longer marked as being away` (Source: RFC2812)
|
||||||
RPL_UNAWAY = 305,
|
RPL_UNAWAY = 305,
|
||||||
/// `306 :You have been marked as being away`
|
/// `306 :You have been marked as being away` (Source: RFC2812)
|
||||||
RPL_NOWAWAY = 306,
|
RPL_NOWAWAY = 306,
|
||||||
/// `311 <nick> <user> <host> * :<real name>`
|
/// `311 <nick> <user> <host> * :<real name>` (Source: RFC2812)
|
||||||
RPL_WHOISUSER = 311,
|
RPL_WHOISUSER = 311,
|
||||||
/// `312 <nick> <server> :<server info>`
|
/// `312 <nick> <server> :<server info>` (Source: RFC2812)
|
||||||
RPL_WHOISSERVER = 312,
|
RPL_WHOISSERVER = 312,
|
||||||
/// `313 <nick> :is an IRC operator`
|
/// `313 <nick> :is an IRC operator` (Source: RFC2812)
|
||||||
RPL_WHOISOPERATOR = 313,
|
RPL_WHOISOPERATOR = 313,
|
||||||
/// `317 <nick> <integer> :seconds idle`
|
/// `317 <nick> <integer> :seconds idle` (Source: RFC2812)
|
||||||
RPL_WHOISIDLE = 317,
|
RPL_WHOISIDLE = 317,
|
||||||
/// `318 <nick> :End of WHOIS list`
|
/// `318 <nick> :End of WHOIS list` (Source: RFC2812)
|
||||||
RPL_ENDOFWHOIS = 318,
|
RPL_ENDOFWHOIS = 318,
|
||||||
/// `319 <nick> :*( ( "@" / "+" ) <channel> " " )`
|
/// `319 <nick> :*( ( "@" / "+" ) <channel> " " )` (Source: RFC2812)
|
||||||
RPL_WHOISCHANNELS = 319,
|
RPL_WHOISCHANNELS = 319,
|
||||||
/// `314 <nick> <user> <host> * :<real name>`
|
/// `314 <nick> <user> <host> * :<real name>` (Source: RFC2812)
|
||||||
RPL_WHOWASUSER = 314,
|
RPL_WHOWASUSER = 314,
|
||||||
/// `369 <nick> :End of WHOWAS`
|
/// `369 <nick> :End of WHOWAS` (Source: RFC2812)
|
||||||
RPL_ENDOFWHOWAS = 369,
|
RPL_ENDOFWHOWAS = 369,
|
||||||
/// Obsolete. Not used.
|
/// Obsolete. Not used. (Source: RFC2812)
|
||||||
RPL_LISTSTART = 321,
|
RPL_LISTSTART = 321,
|
||||||
/// `322 <channel> <# visible> :<topic>`
|
/// `322 <channel> <# visible> :<topic>` (Source: RFC2812)
|
||||||
RPL_LIST = 322,
|
RPL_LIST = 322,
|
||||||
/// `323 :End of LIST
|
/// `323 :End of LIST (Source: RFC2812)
|
||||||
RPL_LISTEND = 323,
|
RPL_LISTEND = 323,
|
||||||
/// `325 <channel> <nickname>`
|
/// `325 <channel> <nickname>` (Source: RFC2812)
|
||||||
RPL_UNIQOPIS = 325,
|
RPL_UNIQOPIS = 325,
|
||||||
/// `324 <channel> <mode> <mode params>`
|
/// `324 <channel> <mode> <mode params>` (Source: RFC2812)
|
||||||
RPL_CHANNELMODEIS = 324,
|
RPL_CHANNELMODEIS = 324,
|
||||||
/// `331 <channel> :No topic is set`
|
/// `331 <channel> :No topic is set` (Source: RFC2812)
|
||||||
RPL_NOTOPIC = 331,
|
RPL_NOTOPIC = 331,
|
||||||
/// `332 <channel> :<topic>`
|
/// `332 <channel> :<topic>` (Source: RFC2812)
|
||||||
RPL_TOPIC = 332,
|
RPL_TOPIC = 332,
|
||||||
/// `333 <channel> <nick>!<user>@<host> <unix timestamp>`
|
/// `333 <channel> <nick>!<user>@<host> <unix timestamp>` (Source: RFC2812)
|
||||||
RPL_TOPICWHOTIME = 333,
|
RPL_TOPICWHOTIME = 333,
|
||||||
/// `341 <channel> <nick>`
|
/// `341 <channel> <nick>` (Source: RFC2812)
|
||||||
RPL_INVITING = 341,
|
RPL_INVITING = 341,
|
||||||
/// `342 <user> :Summoning user to IRC`
|
/// `342 <user> :Summoning user to IRC` (Source: RFC2812)
|
||||||
|
///
|
||||||
|
/// According to Modern, this response is rarely implemented. In practice, people simply message
|
||||||
|
/// one another in a channel with their specified username in the message, rather than use the
|
||||||
|
/// `SUMMON` command.
|
||||||
RPL_SUMMONING = 342,
|
RPL_SUMMONING = 342,
|
||||||
/// `346 <channel> <invitemask>`
|
/// `346 <channel> <invitemask>` (Source: RFC2812)
|
||||||
RPL_INVITELIST = 346,
|
RPL_INVITELIST = 346,
|
||||||
/// `347 <channel> :End of channel invite list`
|
/// `347 <channel> :End of channel invite list` (Source: RFC2812)
|
||||||
|
///
|
||||||
|
/// According to Modern, `RPL_ENDOFEXCEPTLIST` (349) is frequently deployed for this same
|
||||||
|
/// purpose and the difference will be noted in channel mode and the statement in the suffix.
|
||||||
RPL_ENDOFINVITELIST = 347,
|
RPL_ENDOFINVITELIST = 347,
|
||||||
/// `348 <channel> <exceptionmask>`
|
/// `348 <channel> <exceptionmask>` (Source: RFC2812)
|
||||||
RPL_EXCEPTLIST = 348,
|
RPL_EXCEPTLIST = 348,
|
||||||
/// `349 <channel> :End of channel exception list`
|
/// `349 <channel> :End of channel exception list` (Source: RFC2812)
|
||||||
RPL_ENDOFEXCEPTLIST = 349,
|
RPL_ENDOFEXCEPTLIST = 349,
|
||||||
/// `351 <version>.<debuglevel> <server> :<comments>`
|
/// `351 <version> <server> :<comments>` (Source: RFC2812/Modern)
|
||||||
RPL_VERSION = 351,
|
RPL_VERSION = 351,
|
||||||
/** `352 <channel> <user> <host> <server> <nick> ( "H" / "G" > ["*"] [ ( "@" / "+" ) ]
|
/// `352 <channel> <user> <host> <server> <nick> ( "H" / "G" > ["*"] [ ( "@" / "+" ) ]
|
||||||
:<hopcount> <real name>` **/
|
/// :<hopcount> <real name>` (Source: RFC2812)
|
||||||
RPL_WHOREPLY = 352,
|
RPL_WHOREPLY = 352,
|
||||||
/// `315 <name> :End of WHO list`
|
/// `315 <name> :End of WHO list` (Source: RFC2812)
|
||||||
RPL_ENDOFWHO = 315,
|
RPL_ENDOFWHO = 315,
|
||||||
/// `353 ( "=" / "*" / "@" ) <channel> :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )`
|
/// `353 ( "=" / "*" / "@" ) <channel> :[ "@" / "+" ] <nick> *( " " [ "@" / "+" ] <nick> )`
|
||||||
|
/// (Source: RFC2812)
|
||||||
RPL_NAMREPLY = 353,
|
RPL_NAMREPLY = 353,
|
||||||
/// `366 <channel> :End of NAMES list`
|
/// `366 <channel> :End of NAMES list` (Source: RFC2812)
|
||||||
RPL_ENDOFNAMES = 366,
|
RPL_ENDOFNAMES = 366,
|
||||||
/// `364 <mask> <server> :<hopcount> <server info>`
|
/// `364 <mask> <server> :<hopcount> <server info>` (Source: RFC2812)
|
||||||
RPL_LINKS = 364,
|
RPL_LINKS = 364,
|
||||||
/// `365 <mask> :End of LINKS list`
|
/// `365 <mask> :End of LINKS list` (Source: RFC2812)
|
||||||
RPL_ENDOFLINKS = 365,
|
RPL_ENDOFLINKS = 365,
|
||||||
/// `367 <channel> <banmask>`
|
/// `367 <channel> <banmask>` (Source: RFC2812)
|
||||||
RPL_BANLIST = 367,
|
RPL_BANLIST = 367,
|
||||||
/// `368 <channel> :End of channel ban list`
|
/// `368 <channel> :End of channel ban list` (Source: RFC2812)
|
||||||
RPL_ENDOFBANLIST = 368,
|
RPL_ENDOFBANLIST = 368,
|
||||||
/// `371 :<string>`
|
/// `371 :<string>` (Source: RFC2812)
|
||||||
RPL_INFO = 371,
|
RPL_INFO = 371,
|
||||||
/// `374 :End of INFO list`
|
/// `374 :End of INFO list` (Source: RFC2812)
|
||||||
RPL_ENDOFINFO = 374,
|
RPL_ENDOFINFO = 374,
|
||||||
/// `375 :- <server> Message of the day -`
|
/// `375 :- <server> Message of the day -` (Source: RFC2812)
|
||||||
RPL_MOTDSTART = 375,
|
RPL_MOTDSTART = 375,
|
||||||
/// `372 :- <text>`
|
/// `372 :- <text>` (Source: RFC2812)
|
||||||
RPL_MOTD = 372,
|
RPL_MOTD = 372,
|
||||||
/// `376 :End of MOTD command`
|
/// `376 :End of MOTD command` (Source: RFC2812)
|
||||||
RPL_ENDOFMOTD = 376,
|
RPL_ENDOFMOTD = 376,
|
||||||
/// `381 :You are now an IRC operator`
|
/// `381 :You are now an IRC operator` (Source: RFC2812)
|
||||||
RPL_YOUREOPER = 381,
|
RPL_YOUREOPER = 381,
|
||||||
/// `382 <config file> :Rehashing`
|
/// `382 <config file> :Rehashing` (Source: RFC2812)
|
||||||
RPL_REHASHING = 382,
|
RPL_REHASHING = 382,
|
||||||
/// `383 You are service <servicename>`
|
/// `383 You are service <servicename>` (Source: RFC2812)
|
||||||
RPL_YOURESERVICE = 383,
|
RPL_YOURESERVICE = 383,
|
||||||
/// `391 <server> :<string showing server's local time>`
|
/// `391 <server> :<string showing server's local time>` (Source: RFC2812)
|
||||||
RPL_TIME = 391,
|
RPL_TIME = 391,
|
||||||
/// `392 :UserID Terminal Host`
|
/// `392 :UserID Terminal Host` (Source: RFC2812)
|
||||||
RPL_USERSSTART = 392,
|
RPL_USERSSTART = 392,
|
||||||
/// `393 :<username> <ttyline> <hostname>`
|
/// `393 :<username> <ttyline> <hostname>` (Source: RFC2812)
|
||||||
RPL_USERS = 393,
|
RPL_USERS = 393,
|
||||||
/// `394 :End of users`
|
/// `394 :End of users` (Source: RFC2812)
|
||||||
RPL_ENDOFUSERS = 394,
|
RPL_ENDOFUSERS = 394,
|
||||||
/// `395 :Nobody logged in`
|
/// `395 :Nobody logged in` (Source: RFC2812)
|
||||||
RPL_NOUSERS = 395,
|
RPL_NOUSERS = 395,
|
||||||
/** `200 Link <version & debug level> <destination> <next server> V<protocol version>
|
/// `396 <nickname> <host> :is now your displayed host` (Source: InspIRCd)
|
||||||
<link uptime in seconds> <backstream sendq> <upstream sendq>` **/
|
///
|
||||||
|
/// This response code is sent after a user enables the user mode +x (host masking), and it is
|
||||||
|
/// successfully enabled. The particular format described above is from InspIRCd, but the
|
||||||
|
/// response code should be common amongst servers that support host masks.
|
||||||
|
RPL_HOSTHIDDEN = 396,
|
||||||
|
/// `200 Link <version & debug level> <destination> <next server> V<protocol version>
|
||||||
|
/// <link uptime in seconds> <backstream sendq> <upstream sendq>` (Source: RFC2812)
|
||||||
RPL_TRACELINK = 200,
|
RPL_TRACELINK = 200,
|
||||||
/// `201 Try. <class> <server>`
|
/// `201 Try. <class> <server>` (Source: RFC2812)
|
||||||
RPL_TRACECONNECTING = 201,
|
RPL_TRACECONNECTING = 201,
|
||||||
/// `202 H.S. <class> <server>`
|
/// `202 H.S. <class> <server>` (Source: RFC2812)
|
||||||
RPL_TRACEHANDSHAKE = 202,
|
RPL_TRACEHANDSHAKE = 202,
|
||||||
/// `203 ???? <class> [<client IP address in dot form>]`
|
/// `203 ???? <class> [<client IP address in dot form>]` (Source: RFC2812)
|
||||||
RPL_TRACEUKNOWN = 203,
|
RPL_TRACEUKNOWN = 203,
|
||||||
/// `204 Oper <class> <nick>`
|
/// `204 Oper <class> <nick>` (Source: RFC2812)
|
||||||
RPL_TRACEOPERATOR = 204,
|
RPL_TRACEOPERATOR = 204,
|
||||||
/// `205 User <class> <nick>`
|
/// `205 User <class> <nick>` (Source: RFC2812)
|
||||||
RPL_TRACEUSER = 205,
|
RPL_TRACEUSER = 205,
|
||||||
/// `206 Serv <class> <int>S <int>C <server> <nick!user|*!*>@<host|server> V<protocol version>`
|
/// `206 Serv <class> <int>S <int>C <server> <nick!user|*!*>@<host|server> V<protocol version>`
|
||||||
|
/// (Source: RFC2812)
|
||||||
RPL_TRACESERVER = 206,
|
RPL_TRACESERVER = 206,
|
||||||
/// `207 Service <class> <name> <type> <active type>`
|
/// `207 Service <class> <name> <type> <active type>` (Source: RFC2812)
|
||||||
RPL_TRACESERVICE = 207,
|
RPL_TRACESERVICE = 207,
|
||||||
/// `208 <newtype> 0 <client name>`
|
/// `208 <newtype> 0 <client name>` (Source: RFC2812)
|
||||||
RPL_TRACENEWTYPE = 208,
|
RPL_TRACENEWTYPE = 208,
|
||||||
/// `209 Class <class> <count>`
|
/// `209 Class <class> <count>` (Source: RFC2812)
|
||||||
RPL_TRACECLASS = 209,
|
RPL_TRACECLASS = 209,
|
||||||
/// Unused.
|
/// Unused. (Source: RFC2812)
|
||||||
RPL_TRACERECONNECT = 210,
|
RPL_TRACERECONNECT = 210,
|
||||||
/// `261 File <logfile> <debug level>`
|
/// `261 File <logfile> <debug level>` (Source: RFC2812)
|
||||||
RPL_TRACELOG = 261,
|
RPL_TRACELOG = 261,
|
||||||
/// `262 <server name> <version & debug level> :End of TRACE`
|
/// `262 <server name> <version & debug level> :End of TRACE` (Source: RFC2812)
|
||||||
RPL_TRACEEND = 262,
|
RPL_TRACEEND = 262,
|
||||||
/** `211 <linkname> <sendq> <sent messages> <sent Kbytes> <received messages> <received Kbytes>
|
/// `211 <linkname> <sendq> <sent messages> <sent Kbytes> <received messages> <received Kbytes>
|
||||||
<time open>` **/
|
/// <time open>` (Source: RFC2812)
|
||||||
RPL_STATSLINKINFO = 211,
|
RPL_STATSLINKINFO = 211,
|
||||||
/// `212 <command> <count> <byte count> <remote count>`
|
/// `212 <command> <count> <byte count> <remote count>` (Source: RFC2812)
|
||||||
RPL_STATSCOMMANDS = 212,
|
RPL_STATSCOMMANDS = 212,
|
||||||
/// `219 <stats letter> :End of STATS report`
|
/// `219 <stats letter> :End of STATS report` (Source: RFC2812)
|
||||||
RPL_ENDOFSTATS = 219,
|
RPL_ENDOFSTATS = 219,
|
||||||
/// `242 :Server Up %d days %d:%02d:%02d`
|
/// `242 :Server Up %d days %d:%02d:%02d` (Source: RFC2812)
|
||||||
RPL_STATSUPTIME = 242,
|
RPL_STATSUPTIME = 242,
|
||||||
/// `243 O <hostmask> * <name>`
|
/// `243 O <hostmask> * <name>` (Source: RFC2812)
|
||||||
RPL_STATSOLINE = 243,
|
RPL_STATSOLINE = 243,
|
||||||
/// `221 <user mode string>`
|
/// `221 <user mode string>` (Source: RFC2812)
|
||||||
RPL_UMODEIS = 221,
|
RPL_UMODEIS = 221,
|
||||||
/// `234 <name> <server> <mask> <type> <hopcount> <info>`
|
/// `234 <name> <server> <mask> <type> <hopcount> <info>` (Source: RFC2812)
|
||||||
RPL_SERVLIST = 234,
|
RPL_SERVLIST = 234,
|
||||||
/// `235 <mask> <type> :End of service listing`
|
/// `235 <mask> <type> :End of service listing` (Source: RFC2812)
|
||||||
RPL_SERVLISTEND = 235,
|
RPL_SERVLISTEND = 235,
|
||||||
/// `251 :There are <integer> users and <integer> services on <integer> servers`
|
/// `251 :There are <int> users and <int> services on <int> servers` (Source: RFC2812)
|
||||||
RPL_LUSERCLIENT = 251,
|
RPL_LUSERCLIENT = 251,
|
||||||
/// `252 <integer> :operator(s) online`
|
/// `252 <integer> :operator(s) online` (Source: RFC2812)
|
||||||
RPL_LUSEROP = 252,
|
RPL_LUSEROP = 252,
|
||||||
/// `253 <integer> :unknown connection(s)`
|
/// `253 <integer> :unknown connection(s)` (Source: RFC2812)
|
||||||
RPL_LUSERUNKNOWN = 253,
|
RPL_LUSERUNKNOWN = 253,
|
||||||
/// `254 <integer> :channels formed`
|
/// `254 <integer> :channels formed` (Source: RFC2812)
|
||||||
RPL_LUSERCHANNELS = 254,
|
RPL_LUSERCHANNELS = 254,
|
||||||
/// `255 :I have <integer> clients and <integer> servers`
|
/// `255 :I have <integer> clients and <integer> servers` (Source: RFC2812)
|
||||||
RPL_LUSERME = 255,
|
RPL_LUSERME = 255,
|
||||||
/// `256 <server> :Administrative info`
|
/// `256 <server> :Administrative info` (Source: RFC2812)
|
||||||
RPL_ADMINME = 256,
|
RPL_ADMINME = 256,
|
||||||
/// `257 :<admin info>`
|
/// `257 :<admin info>` (Source: RFC2812)
|
||||||
RPL_ADMINLOC1 = 257,
|
RPL_ADMINLOC1 = 257,
|
||||||
/// `258 :<admin info>`
|
/// `258 :<admin info>` (Source: RFC2812)
|
||||||
RPL_ADMINLOC2 = 258,
|
RPL_ADMINLOC2 = 258,
|
||||||
/// `259 :<admin info>`
|
/// `259 :<admin info>` (Source: RFC2812)
|
||||||
RPL_ADMINEMAIL = 259,
|
RPL_ADMINEMAIL = 259,
|
||||||
/// `263 <command> :Please wait a while and try again.`
|
/// `263 <command> :Please wait a while and try again.` (Source: RFC2812)
|
||||||
RPL_TRYAGAIN = 263,
|
RPL_TRYAGAIN = 263,
|
||||||
/// `730 <nick> :target[,target2]*`
|
/// `265 <client> [<u> <m>] :Current local users <u>, max <m>` (Source: Modern)
|
||||||
|
RPL_LOCALUSERS = 265,
|
||||||
|
/// `266 <client> [<u> <m>] :Current local users <u>, max <m>` (Source: Modern)
|
||||||
|
RPL_GLOBALUSERS = 266,
|
||||||
|
/// `276 <client> <nick> :has client certificate fingerprint <fingerprint>` (Source: Modern)
|
||||||
|
RPL_WHOISCERTFP = 276,
|
||||||
|
/// `730 <nick> :target[,target2]*` (Source: RFC2812)
|
||||||
RPL_MONONLINE = 730,
|
RPL_MONONLINE = 730,
|
||||||
/// `731 <nick> :target[,target2]*`
|
/// `731 <nick> :target[,target2]*` (Source: RFC2812)
|
||||||
RPL_MONOFFLINE = 731,
|
RPL_MONOFFLINE = 731,
|
||||||
/// `732 <nick> :target[,target2]*`
|
/// `732 <nick> :target[,target2]*` (Source: RFC2812)
|
||||||
RPL_MONLIST = 732,
|
RPL_MONLIST = 732,
|
||||||
/// `733 <nick> :End of MONITOR list`
|
/// `733 <nick> :End of MONITOR list` (Source: RFC2812)
|
||||||
RPL_ENDOFMONLIST = 733,
|
RPL_ENDOFMONLIST = 733,
|
||||||
/// `760 <target> <key> <visibility> :<value>`
|
/// `760 <target> <key> <visibility> :<value>` (Source: RFC2812)
|
||||||
RPL_WHOISKEYVALUE = 760,
|
RPL_WHOISKEYVALUE = 760,
|
||||||
/// `761 <target> <key> <visibility> :[<value>]`
|
/// `761 <target> <key> <visibility> :[<value>]` (Source: RFC2812)
|
||||||
RPL_KEYVALUE = 761,
|
RPL_KEYVALUE = 761,
|
||||||
/// `762 :end of metadata`
|
/// `762 :end of metadata` (Source: RFC2812)
|
||||||
RPL_METADATAEND = 762,
|
RPL_METADATAEND = 762,
|
||||||
/// `900 <nick> <nick>!<ident>@<host> <account> :You are now logged in as <user>`
|
/// `900 <nick> <nick>!<ident>@<host> <account> :You are now logged in as <user>` (Source:
|
||||||
|
/// IRCv3)
|
||||||
RPL_LOGGEDIN = 900,
|
RPL_LOGGEDIN = 900,
|
||||||
/// `901 <nick> <nick>!<ident>@<host> :You are now logged out`
|
/// `901 <nick> <nick>!<ident>@<host> :You are now logged out` (Source: IRCv3)
|
||||||
RPL_LOGGEDOUT = 901,
|
RPL_LOGGEDOUT = 901,
|
||||||
/// `903 <nick> :SASL authentication successful`
|
/// `903 <nick> :SASL authentication successful` (Source: IRCv3)
|
||||||
RPL_SASLSUCCESS = 903,
|
RPL_SASLSUCCESS = 903,
|
||||||
/// `908 <nick> <mechanisms> :are available SASL mechanisms`
|
/// `908 <nick> <mechanisms> :are available SASL mechanisms` (Source: IRCv3)
|
||||||
RPL_SASLMECHS = 908,
|
RPL_SASLMECHS = 908,
|
||||||
|
|
||||||
// Error replies
|
// Error replies
|
||||||
/// `401 <nickname> :No such nick/channel`
|
/// `400 <client> <command>{ <subcommand>} :<info>` (Source: Modern)
|
||||||
|
///
|
||||||
|
/// According to Modern, this error will be returned when the given command/subcommand could not
|
||||||
|
/// be processed. It's a very general error, and should only be used when more specific numerics
|
||||||
|
/// do not suffice.
|
||||||
|
ERR_UNKNOWNERROR = 400,
|
||||||
|
/// `401 <nickname> :No such nick/channel` (Source: RFC2812)
|
||||||
ERR_NOSUCHNICK = 401,
|
ERR_NOSUCHNICK = 401,
|
||||||
/// `402 <server name> :No such server`
|
/// `402 <server name> :No such server` (Source: RFC2812)
|
||||||
ERR_NOSUCHSERVER = 402,
|
ERR_NOSUCHSERVER = 402,
|
||||||
/// `403 <channel name> :No such channel`
|
/// `403 <channel name> :No such channel` (Source: RFC2812)
|
||||||
ERR_NOSUCHCHANNEL = 403,
|
ERR_NOSUCHCHANNEL = 403,
|
||||||
/// `404 <channel name> :Cannot send to channel`
|
/// `404 <channel name> :Cannot send to channel` (Source: RFC2812)
|
||||||
ERR_CANNOTSENDTOCHAN = 404,
|
ERR_CANNOTSENDTOCHAN = 404,
|
||||||
/// `405 <channel name> :You have joined too many channels`
|
/// `405 <channel name> :You have joined too many channels` (Source: RFC2812)
|
||||||
ERR_TOOMANYCHANNELS = 405,
|
ERR_TOOMANYCHANNELS = 405,
|
||||||
/// `406 <nickname> :There was no such nickname`
|
/// `406 <nickname> :There was no such nickname` (Source: RFC2812)
|
||||||
ERR_WASNOSUCHNICK = 406,
|
ERR_WASNOSUCHNICK = 406,
|
||||||
/// `407 <target> :<error code> recipients. <abort message>`
|
/// `407 <target> :<error code> recipients. <abort message>` (Source: RFC2812)
|
||||||
ERR_TOOMANYTARGETS = 407,
|
ERR_TOOMANYTARGETS = 407,
|
||||||
/// `408 <service name> :No such service`
|
/// `408 <service name> :No such service` (Source: RFC2812)
|
||||||
ERR_NOSUCHSERVICE = 408,
|
ERR_NOSUCHSERVICE = 408,
|
||||||
/// `409 :No origin specified`
|
/// `409 :No origin specified` (Source: RFC2812)
|
||||||
ERR_NOORIGIN = 409,
|
ERR_NOORIGIN = 409,
|
||||||
/// `411 :No recipient given (<command>)`
|
/// `411 :No recipient given (<command>)` (Source: RFC2812)
|
||||||
ERR_NORECIPIENT = 411,
|
ERR_NORECIPIENT = 411,
|
||||||
/// `412 :No text to send`
|
/// `412 :No text to send` (Source: RFC2812)
|
||||||
ERR_NOTEXTTOSEND = 412,
|
ERR_NOTEXTTOSEND = 412,
|
||||||
/// `413 <mask> :No toplevel domain specified`
|
/// `413 <mask> :No toplevel domain specified` (Source: RFC2812)
|
||||||
ERR_NOTOPLEVEL = 413,
|
ERR_NOTOPLEVEL = 413,
|
||||||
/// `414 <mask> :Wildcard in toplevel domain`
|
/// `414 <mask> :Wildcard in toplevel domain` (Source: RFC2812)
|
||||||
ERR_WILDTOPLEVEL = 414,
|
ERR_WILDTOPLEVEL = 414,
|
||||||
/// `415 <mask> :Bad Server/host mask`
|
/// `415 <mask> :Bad Server/host mask` (Source: RFC2812)
|
||||||
ERR_BADMASK = 415,
|
ERR_BADMASK = 415,
|
||||||
/// `421 <command> :Unknown command`
|
/// `421 <command> :Unknown command` (Source: RFC2812)
|
||||||
ERR_UNKNOWNCOMMAND = 421,
|
ERR_UNKNOWNCOMMAND = 421,
|
||||||
/// `422 :MOTD File is missing`
|
/// `422 :MOTD File is missing` (Source: RFC2812)
|
||||||
ERR_NOMOTD = 422,
|
ERR_NOMOTD = 422,
|
||||||
/// `423 <server> :No administrative info available`
|
/// `423 <server> :No administrative info available` (Source: RFC2812)
|
||||||
ERR_NOADMININFO = 423,
|
ERR_NOADMININFO = 423,
|
||||||
/// `424 :File error doing <file op> on <file>`
|
/// `424 :File error doing <file op> on <file>` (Source: RFC2812)
|
||||||
ERR_FILEERROR = 424,
|
ERR_FILEERROR = 424,
|
||||||
/// `431 :No nickname given`
|
/// `431 :No nickname given` (Source: RFC2812)
|
||||||
ERR_NONICKNAMEGIVEN = 431,
|
ERR_NONICKNAMEGIVEN = 431,
|
||||||
/// `432 <nick> :Erroneous nickname"`
|
/// `432 <nick> :Erroneous nickname"` (Source: RFC2812)
|
||||||
ERR_ERRONEOUSNICKNAME = 432,
|
ERR_ERRONEOUSNICKNAME = 432,
|
||||||
/// `433 <nick> :Nickname is already in use`
|
/// `433 <nick> :Nickname is already in use` (Source: RFC2812)
|
||||||
ERR_NICKNAMEINUSE = 433,
|
ERR_NICKNAMEINUSE = 433,
|
||||||
/// `436 <nick> :Nickname collision KILL from <user>@<host>`
|
/// `436 <nick> :Nickname collision KILL from <user>@<host>` (Source: RFC2812)
|
||||||
ERR_NICKCOLLISION = 436,
|
ERR_NICKCOLLISION = 436,
|
||||||
/// `437 <nick/channel> :Nick/channel is temporarily unavailable`
|
/// `437 <nick/channel> :Nick/channel is temporarily unavailable` (Source: RFC2812)
|
||||||
ERR_UNAVAILRESOURCE = 437,
|
ERR_UNAVAILRESOURCE = 437,
|
||||||
/// `441 <nick> <channel> :They aren't on that channel`
|
/// `441 <nick> <channel> :They aren't on that channel` (Source: RFC2812)
|
||||||
ERR_USERNOTINCHANNEL = 441,
|
ERR_USERNOTINCHANNEL = 441,
|
||||||
/// `442 <channel> :You're not on that channel`
|
/// `442 <channel> :You're not on that channel` (Source: RFC2812)
|
||||||
ERR_NOTONCHANNEL = 442,
|
ERR_NOTONCHANNEL = 442,
|
||||||
/// `443 <user> <channel> :is already on channel`
|
/// `443 <user> <channel> :is already on channel` (Source: RFC2812)
|
||||||
ERR_USERONCHANNEL = 443,
|
ERR_USERONCHANNEL = 443,
|
||||||
/// `444 <user> :User not logged in`
|
/// `444 <user> :User not logged in` (Source: RFC2812)
|
||||||
ERR_NOLOGIN = 444,
|
ERR_NOLOGIN = 444,
|
||||||
/// `445 :SUMMON has been disabled`
|
/// `445 :SUMMON has been disabled` (Source: RFC2812)
|
||||||
ERR_SUMMONDISABLED = 445,
|
ERR_SUMMONDISABLED = 445,
|
||||||
/// `446 :USERS has been disabled`
|
/// `446 :USERS has been disabled` (Source: RFC2812)
|
||||||
ERR_USERSDISABLED = 446,
|
ERR_USERSDISABLED = 446,
|
||||||
/// `451 :You have not registered`
|
/// `451 :You have not registered` (Source: RFC2812)
|
||||||
ERR_NOTREGISTERED = 451,
|
ERR_NOTREGISTERED = 451,
|
||||||
/// `461 <command> :Not enough parameters`
|
/// `461 <command> :Not enough parameters` (Source: RFC2812)
|
||||||
ERR_NEEDMOREPARAMS = 461,
|
ERR_NEEDMOREPARAMS = 461,
|
||||||
/// `462 :Unauthorized command (already registered)`
|
/// `462 :Unauthorized command (already registered)` (Source: RFC2812)
|
||||||
ERR_ALREADYREGISTRED = 462,
|
ERR_ALREADYREGISTRED = 462,
|
||||||
/// `463 :Your host isn't among the privileged`
|
/// `463 :Your host isn't among the privileged` (Source: RFC2812)
|
||||||
ERR_NOPERMFORHOST = 463,
|
ERR_NOPERMFORHOST = 463,
|
||||||
/// `464 :Password incorrect`
|
/// `464 :Password incorrect` (Source: RFC2812)
|
||||||
ERR_PASSWDMISMATCH = 464,
|
ERR_PASSWDMISMATCH = 464,
|
||||||
/// `465 :You are banned from this server`
|
/// `465 :You are banned from this server` (Source: RFC2812)
|
||||||
ERR_YOUREBANNEDCREEP = 465,
|
ERR_YOUREBANNEDCREEP = 465,
|
||||||
/// `466`
|
/// `466` (Source: RFC2812)
|
||||||
ERR_YOUWILLBEBANNED = 466,
|
ERR_YOUWILLBEBANNED = 466,
|
||||||
/// `467 <channel> :Channel key already set`
|
/// `467 <channel> :Channel key already set` (Source: RFC2812)
|
||||||
ERR_KEYSET = 467,
|
ERR_KEYSET = 467,
|
||||||
/// `471 <channel> :Cannot join channel (+l)`
|
/// `471 <channel> :Cannot join channel (+l)` (Source: RFC2812)
|
||||||
ERR_CHANNELISFULL = 471,
|
ERR_CHANNELISFULL = 471,
|
||||||
/// `472 <char> :is unknown mode char to me for <channel>`
|
/// `472 <char> :is unknown mode char to me for <channel>` (Source: RFC2812)
|
||||||
ERR_UNKNOWNMODE = 472,
|
ERR_UNKNOWNMODE = 472,
|
||||||
/// `473 <channel> :Cannot join channel (+i)`
|
/// `473 <channel> :Cannot join channel (+i)` (Source: RFC2812)
|
||||||
ERR_INVITEONLYCHAN = 473,
|
ERR_INVITEONLYCHAN = 473,
|
||||||
/// `474 <channel> :Cannot join channel (+b)`
|
/// `474 <channel> :Cannot join channel (+b)` (Source: RFC2812)
|
||||||
ERR_BANNEDFROMCHAN = 474,
|
ERR_BANNEDFROMCHAN = 474,
|
||||||
/// `475 <channel> :Cannot join channel (+k)`
|
/// `475 <channel> :Cannot join channel (+k)` (Source: RFC2812)
|
||||||
ERR_BADCHANNELKEY = 475,
|
ERR_BADCHANNELKEY = 475,
|
||||||
/// `476 <channel> :Bad Channel Mask`
|
/// `476 <channel> :Bad Channel Mask` (Source: RFC2812)
|
||||||
ERR_BADCHANMASK = 476,
|
ERR_BADCHANMASK = 476,
|
||||||
/// `477 <channel> :Channel doesn't support modes`
|
/// `477 <channel> :Channel doesn't support modes` (Source: RFC2812)
|
||||||
ERR_NOCHANMODES = 477,
|
ERR_NOCHANMODES = 477,
|
||||||
/// `478 <channel> <char> :Channel list is full`
|
/// `478 <channel> <char> :Channel list is full` (Source: RFC2812)
|
||||||
ERR_BANLISTFULL = 478,
|
ERR_BANLISTFULL = 478,
|
||||||
/// `481 :Permission Denied- You're not an IRC operator`
|
/// `481 :Permission Denied- You're not an IRC operator` (Source: RFC2812)
|
||||||
ERR_NOPRIVILEGES = 481,
|
ERR_NOPRIVILEGES = 481,
|
||||||
/// `482 <channel> :You're not channel operator`
|
/// `482 <channel> :You're not channel operator` (Source: RFC2812)
|
||||||
ERR_CHANOPRIVSNEEDED = 482,
|
ERR_CHANOPRIVSNEEDED = 482,
|
||||||
/// `483 :You can't kill a server!`
|
/// `483 :You can't kill a server!` (Source: RFC2812)
|
||||||
ERR_CANTKILLSERVER = 483,
|
ERR_CANTKILLSERVER = 483,
|
||||||
/// `484 :Your connection is restricted!`
|
/// `484 :Your connection is restricted!` (Source: RFC2812)
|
||||||
ERR_RESTRICTED = 484,
|
ERR_RESTRICTED = 484,
|
||||||
/// `485 :You're not the original channel operator`
|
/// `485 :You're not the original channel operator` (Source: RFC2812)
|
||||||
ERR_UNIQOPPRIVSNEEDED = 485,
|
ERR_UNIQOPPRIVSNEEDED = 485,
|
||||||
/// `491 :No O-lines for your host`
|
/// `491 :No O-lines for your host` (Source: RFC2812)
|
||||||
ERR_NOOPERHOST = 491,
|
ERR_NOOPERHOST = 491,
|
||||||
/// `501 :Unknown MODE flag`
|
/// `501 :Unknown MODE flag` (Source: RFC2812)
|
||||||
ERR_UMODEUNKNOWNFLAG = 501,
|
ERR_UMODEUNKNOWNFLAG = 501,
|
||||||
/// `502 :Cannot change mode for other users`
|
/// `502 :Cannot change mode for other users` (Source: RFC2812)
|
||||||
ERR_USERSDONTMATCH = 502,
|
ERR_USERSDONTMATCH = 502,
|
||||||
/// `734 <nick> <limit> <targets> :Monitor list is full.`
|
/// `723 <client> <priv> :Insufficient oper privileges.` (Source: Modern)
|
||||||
|
///
|
||||||
|
/// Sent to an operator to indicate that they don't have the specific privileges to perform the
|
||||||
|
/// desired action. The format and meaning of the privilege string is server-defined.
|
||||||
|
ERR_NOPRIVS = 723,
|
||||||
|
/// `734 <nick> <limit> <targets> :Monitor list is full.` (Source: RFC2812)
|
||||||
ERR_MONLISTFULL = 734,
|
ERR_MONLISTFULL = 734,
|
||||||
/// `764 <target> :metadata limit reached`
|
/// `764 <target> :metadata limit reached` (Source: RFC2812)
|
||||||
ERR_METADATALIMIT = 764,
|
ERR_METADATALIMIT = 764,
|
||||||
/// `765 <target> :invalid metadata target`
|
/// `765 <target> :invalid metadata target` (Source: RFC2812)
|
||||||
ERR_TARGETINVALID = 765,
|
ERR_TARGETINVALID = 765,
|
||||||
/// `766 <key> :no matching key`
|
/// `766 <key> :no matching key` (Source: RFC2812)
|
||||||
ERR_NOMATCHINGKEY = 766,
|
ERR_NOMATCHINGKEY = 766,
|
||||||
/// `767 <key> :invalid metadata key`
|
/// `767 <key> :invalid metadata key` (Source: RFC2812)
|
||||||
ERR_KEYINVALID = 767,
|
ERR_KEYINVALID = 767,
|
||||||
/// `768 <target> <key> :key not set`
|
/// `768 <target> <key> :key not set` (Source: RFC2812)
|
||||||
ERR_KEYNOTSET = 768,
|
ERR_KEYNOTSET = 768,
|
||||||
/// `769 <target> <key> :permission denied`
|
/// `769 <target> <key> :permission denied` (Source: RFC2812)
|
||||||
ERR_KEYNOPERMISSION = 769,
|
ERR_KEYNOPERMISSION = 769,
|
||||||
/// `902 <nick> :You must use a nick assigned to you.`
|
/// `902 <nick> :You must use a nick assigned to you.` (Source: IRCv3)
|
||||||
ERR_NICKLOCKED = 902,
|
ERR_NICKLOCKED = 902,
|
||||||
/// `904 <nick> :SASL authentication failed`
|
/// `904 <nick> :SASL authentication failed` (Source: IRCv3)
|
||||||
ERR_SASLFAIL = 904,
|
ERR_SASLFAIL = 904,
|
||||||
/// `905 <nick> :SASL message too long`
|
/// `905 <nick> :SASL message too long` (Source: IRCv3)
|
||||||
ERR_SASLTOOLONG = 905,
|
ERR_SASLTOOLONG = 905,
|
||||||
/// `906 <nick> :SASL authentication aborted`
|
/// `906 <nick> :SASL authentication aborted` (Source: IRCv3)
|
||||||
ERR_SASLABORT = 906,
|
ERR_SASLABORT = 906,
|
||||||
/// `907 <nick> :You have already authenticated using SASL`
|
/// `907 <nick> :You have already authenticated using SASL` (Source: IRCv3)
|
||||||
ERR_SASLALREADY = 907
|
ERR_SASLALREADY = 907
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl Response {
|
||||||
/// Determines whether or not this response is an error response.
|
/// Determines whether or not this response is an error response.
|
||||||
|
///
|
||||||
|
/// This error consideration is according to RFC2812, but is rather simplistic. It considers all
|
||||||
|
/// response codes above 400 to be errors, which misclassifies some extensions (e.g. from IRCv3)
|
||||||
|
/// that add responses and errors both in the same range (typically 700s or 900s).
|
||||||
pub fn is_error(&self) -> bool {
|
pub fn is_error(&self) -> bool {
|
||||||
*self as u16 >= 400
|
*self as u16 >= 400
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue