Expand description
Derive macros for FromMessage and ToMessage traits from ircv3_parse.
§Attributes
When no explicit key is specified, the field name is used as the key, converted to kebab-case.
#[irc(command = "CMD")] is optional for structs and unit structs.
§Struct
#[derive(FromMessage, ToMessage)]
#[irc(command = "PRIVMSG")]
struct PrivMsg<'a> {
#[irc(tag = "id")]
id: &'a str,
#[irc(source)]
nick: &'a str,
#[irc(param)]
channel: &'a str,
#[irc(trailing)]
text: &'a str,
}The container attribute #[irc(command = "CMD")] checks the command on deserialization and writes it on serialization.
§Tags
§Tag
#[irc(tag)]
#[irc(tag = "key")]§Tag Flag
#[irc(tag_flag)]
#[irc(tag_flag = "key")]Supports bool, Option<T>, or a nested type.
§Source
#[irc(source)] // source.name
#[irc(source = "name")]
#[irc(source = "user")]
#[irc(source = "host")]§Param
#[irc(param)] // first param (index 0)
#[irc(param = 1)] // second param
#[irc(params)] // all paramsVec<T> is only valid with #[irc(params)].
§Trailing
#[irc(trailing)]&str/Stringnever fails - yields an empty string when absent.Option<T>yieldsNonewhen absent or empty (empty string is treated asNone).
§Command
#[irc(command)]Does not support Option.
§Nested
A field with no #[irc(...)] attribute delegates to that type’s own FromMessage/ToMessage implementation.
§Unit Struct
Unit structs validate that a message matches expected values without extracting data, and write those values on serialization.
#[derive(FromMessage, ToMessage)]
#[irc(command = "PING", tag = "src", value = "server")]
struct PingFromServer;#[irc(command = "CMD")]- matches/writes the command#[irc(tag = "key")],#[irc(param)], etc. - matches/writes a specific component value#[irc(value = "...")]- overrides the expected value (default: kebab-case of the struct name)
§Enum
Enums match a single IRC component value against variant patterns.
#[derive(FromMessage, ToMessage)]
#[irc(command)]
enum Command {
PrivMsg,
Join,
Part,
}§Container Attributes
#[irc(command)]
#[irc(tag)]
#[irc(tag = "key")]
#[irc(tag_flag)]
#[irc(tag_flag = "key")]
#[irc(source)]
#[irc(source = "name|user|host")]
#[irc(param)]
#[irc(param = N)]
#[irc(trailing)]#[irc(rename_all = "lowercase|UPPERCASE|kebab-case")]- rename all variants (default:kebab-case, exceptcommandwhich defaults toUPPERCASE)
When no key is specified, the enum name is used as the tag key (always kebab-case, independent of rename_all).
§Variant Attributes
#[irc(value = "...")]- override the match/serialization value (can appear multiple times. seepickfor serialization with multiple values)#[irc(present)]- fortag_flagenums, marks the variant matched when the flag is present
#[derive(FromMessage, ToMessage)]
#[irc(tag = "badge-info")]
enum Badge {
#[irc(value = "subscriber", pick)]
#[irc(value = "sub")]
Subscriber,
Moderator,
}
#[derive(FromMessage, ToMessage)]
#[irc(tag_flag = "mod")]
enum Mod {
#[irc(present)]
Moderator,
Regular,
}tag_flag enums require exactly two variants:
- one marked
#[irc(present)]- matched when the flag is present - one absent variant - matched when the flag is absent. must be a unit variant
§Enum Fields
Variants can carry fields that extract additional IRC components.
#[derive(FromMessage, ToMessage)]
#[irc(command)]
enum Command {
PrivMsg {
#[irc(param)]
channel: String,
#[irc(trailing)]
text: String,
},
Join(#[irc(param)] String),
Part,
}When a variant has a single unnamed field with no #[irc(...)] attribute, the field carries the matched component value directly.
#[derive(FromMessage, ToMessage)]
#[irc(tag = "color")]
enum Color {
Red,
Blue,
Other(String),
}§Deserialization (FromMessage)
§Field Options
§with
Provides a custom deserializer function. The function receives the raw component input.
#[irc(tag = "ts", with = "parse_timestamp")]
timestamp: u64,
fn parse_timestamp(value: Option<&str>) -> u64 {
value.and_then(|s| s.parse().ok()).unwrap_or(0)
}§default
Uses a fallback value when the component is absent instead of returning an error.
#[irc(tag = "color", default)] // Default::default()
#[irc(tag = "color", default = "red_fn")] // red_fn()§Enum
#[irc(default = "VariantName")]- catch-all unit variant for unrecognized values
§Serialization (ToMessage)
§Container
#[irc(crlf)]- appends\r\nand validates the message is complete:- command must be set (
#[irc(command = "...")]or#[irc(command)]field) #[irc(source = "user")]or#[irc(source = "host")]requires#[irc(source)]to also be present
- command must be set (
§Field Options
§skip
Always skip this field during serialization.
#[irc(tag = "internal", skip)]§skip_none
Skip the tag entirely when the value is None. Only allowed on #[irc(tag)] fields with Option<String> or Option<&str> type.
Without skip_none, None writes key= (tag present with no value). With skip_none, None omits the tag entirely.
#[irc(tag = "msgid", skip_none)]
id: Option<String>, // None -> tag absent, Some(v) -> @msgid=v
#[irc(tag = "msgid")]
id: Option<String>, // None -> @msgid=§Enum Variant
#[irc(pick)]- when a variant has multiple#[irc(value)], selects which one to use for serialization
#[derive(ToMessage)]
#[irc(command)]
enum Command {
#[irc(value = "PRIVMSG", pick)]
#[irc(value = "NOTICE")]
Message, // serializes as PRIVMSG
}