Expand description
Zero-copy IRC message parser with IRCv3 support.
§Quick Start
§Using Derive Macro (Recommended)
use ircv3_parse::FromMessage;
#[derive(FromMessage)]
#[irc(command = "PRIVMSG")]
struct PrivMsg<'a> {
#[irc(source = "name")]
nick: &'a str,
#[irc(trailing)]
message: &'a str
}
let input = ":nick!user@example.com PRIVMSG #channel :Hello everyone!";
let msg: PrivMsg = ircv3_parse::from_str(input)?;
println!("From: {}", msg.nick);
println!("Message: {}", msg.message);§FromMessage Derive Attributes
The FromMessage derive macro supports both &str and String field types.
§Struct-Level Attributes
#[irc(command = "COMMAND")]- Validates that the command matches (case-insensitive)
§Field-Level Attributes
#[irc(tag = "key")]- Extract tag value#[irc(tag_flag = "key")]- Extract tag flag#[irc(source = "component")]- Extract source component (name,user, orhost)#[irc(param = N)]- Extract parameter by index#[irc(params)]- Extract all parameters into aVec#[irc(trailing)]- Extract trailing parameter#[irc(command)]- Extract command#[irc(with = "function")]- Custom extraction
§Manual FromMessage Implementation
For more complex parsing logic, implement the FromMessage trait manually.
§Understanding Message Structure
The Message struct provides access to IRC message components:
Message::tags()- ReturnsTagsMessage::source()- ReturnsSourceMessage::command()- ReturnsCommandsMessage::params()- ReturnsParams
§Example Implementation
use ircv3_parse::{message::de::FromMessage, DeError, Message};
struct PrivMsg<'a> {
color: Option<&'a str>,
channel: &'a str,
nick: &'a str,
message: &'a str,
}
impl<'a> FromMessage<'a> for PrivMsg<'a> {
fn from_message(msg: &Message<'a>) -> Result<Self, DeError> {
// Validate command
let command = msg.command();
if !command.is_privmsg() {
return Err(DeError::invalid_command("PRIVMSG", command.as_str()));
}
// Extract tags (optional)
let color = msg.tags()
.and_then(|tags| tags.get("color"))
.map(|v| v.as_str());
// Extract source (required)
let source = msg.source()
.ok_or_else(|| DeError::missing_source())?;
let nick = source.name;
// Extract parameters
let params = msg.params();
let channel = params.middles.first()
.ok_or_else(|| DeError::missing_param_field("channel", 0))?;
let message = params.trailing.as_str();
Ok(Self {
color,
channel,
nick,
message,
})
}
}§Error Handling
use ircv3_parse::FromMessage;
#[derive(FromMessage)]
#[irc(command = "PRIVMSG")]
struct PrivMsg {
#[irc(trailing)]
message: String
}
let input = "NOTICE all :hi";
let result = ircv3_parse::from_str::<PrivMsg>(input);
if let Err(e) = result {
if e.is_parse_error() {
println!("Invalid IRC message format: {e}");
}
if e.is_invalid_command() {
println!("Expected PRIVMSG, got {input}");
}
if e.is_missing_tags() {
println!("Message has no tags component");
}
if e.is_missing_source() {
println!("Message has no source component");
}
if e.is_missing_param() {
println!("Message has no parameters");
}
if e.is_missing_tag() {
println!("Specific tag not found");
}
}§Building Messages
use ircv3_parse::{builder::legacy::MessageBuilder, components::Commands};
let message = MessageBuilder::new(Commands::PRIVMSG)
.with_tags(|tags| {
tags.add("id", Some("123"))?
.add("color", None)?
.add_flag("subscriber")
})?
.with_source("nick", |source| {
source.with_user("user")?.with_host("example.com")
})?
.with_params(|params| params.add("#channel"))?
.with_trailing("hi")?
.finish();
let bytes = message.to_bytes();
// Result: @id=123;color=;subscriber :nick!user@example.com PRIVMSG #channel :hi\r\n§Builder Order
Components must be added in the correct order:
- Command (required) -
MessageBuilder::new()withCommands - Tags (optional) -
with_tags() - Source (optional) -
with_source() - Middle parameters (optional) -
with_params() - Trailing parameter (optional) -
with_trailing()
§Feature Flags
derive- Enables theFromMessagederive macroserde- EnablesSerializeimplementation forMessage
Re-exports§
pub use components::Commands;pub use error::DeError;pub use error::IRCError;pub use message::Message;pub use message::MessageBuilder;
Modules§
Functions§
- from_
message - Serialize the custom data structure as a Bytes.
- from_
str - Parse an IRC message into a type implementing
message::de::FromMessage. - parse
- Parse an IRC message from a string.
- unescape
- Unescapes an IRCv3 tag value according to the specification.
Derive Macros§
- From
Message derive - Derives
FromMessageimplementation for structs