lavina/src/protos/irc/mod.rs

52 lines
1.3 KiB
Rust

//! Client-to-Server IRC protocol.
pub mod client;
pub mod server;
use std::io::Write;
use nom::{
branch::alt,
bytes::complete::{tag, take, take_while},
IResult,
};
type ByteVec = Vec<u8>;
/// Single message tag value.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Tag {
key: ByteVec,
value: Option<u8>,
}
fn receiver(input: &[u8]) -> IResult<&[u8], &[u8]> {
take_while(|i| i != b'\n' && i != b'\r' && i != b' ')(input)
}
fn token(input: &[u8]) -> IResult<&[u8], &[u8]> {
take_while(|i| i != b'\n' && i != b'\r')(input)
}
pub enum Chan {
/// #<name> — network-global channel, available from any server in the network.
Global(ByteVec),
/// &<name> — server-local channel, available only to connections to the same server. Rarely used in practice.
Local(ByteVec),
}
fn chan(input: &[u8]) -> IResult<&[u8], Chan> {
fn chan_global(input: &[u8]) -> IResult<&[u8], Chan> {
let (input, _) = tag("#")(input)?;
let (input, name) = receiver(input)?;
Ok((input, Chan::Global(name.to_vec())))
}
fn chan_local(input: &[u8]) -> IResult<&[u8], Chan> {
let (input, _) = tag("&")(input)?;
let (input, name) = receiver(input)?;
Ok((input, Chan::Local(name.to_vec())))
}
alt((chan_global, chan_local))(input)
}