aatxe / irc

the irc crate – usable, async IRC for Rust
Mozilla Public License 2.0
525 stars 100 forks source link

Allow for custom message parsers #245

Open snowpoke opened 1 year ago

snowpoke commented 1 year ago

At the moment, any IRC message is parsed as an entity of class Message:

pub struct Message {
    pub tags: Option<Vec<Tag>>,
    pub prefix: Option<Prefix>,
    pub command: Command,
}

However, some users may want to use adjusted versions of this type, or skip parsing altogether. It would be nice if this was possible without maintaining a custom fork of the crate.

So I generalized a lot of code relating to message interpretation and redefined the Client structure as this:

pub struct Client<Codec = DefaultCodec>
where
    Codec: MessageCodec,
    error::Error: From<<Codec as Decoder>::Error> + From<<Codec as Encoder<Codec::MsgItem>>::Error>,
    Codec::MsgItem: InternalIrcMessageOutgoing + InternalIrcMessageIncoming,
{
    state: Arc<ClientState<Codec>>,
    incoming: Option<SplitStream<Connection<Codec>>>,
    outgoing: Option<Outgoing<Codec>>,
    sender: Sender<Codec::MsgItem>,
}

This means that the new code is mostly backward-compatible, and if you want to use the crate with a custom IRC message parser, you can construct it as follows:

    let mut client = Client::<NoParseCodec>::from_config_with_codec(config).await?;

Of note, I have added a semver-breaking feature called essentials. Basically, at this point I only wanted to write a minimum working example of a custom parser, so I gated a lot of features behind the essentials feature. If you remove this feature (as is required for the NoParseCodec to work), it removes all features from the client except for those strictly required to run an IRC client.

I'm currently successfully running a Twitch Chat scraper-like program using the NoParseCodec modification.

Btw it would be possible to adjust this code to be (mostly?) semver-compliant, but since the changes behind the scenes (and the potential for unexpected errors) are so big, I'm not sure if it's worth it.