//! Client-to-Server IRC protocol. pub mod client; pub mod server; use nom::{ branch::alt, bytes::complete::{tag, take, take_while}, IResult, }; type ByteVec = Vec; /// Single message tag value. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Tag { key: ByteVec, value: Option, } 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) } #[derive(Clone, Debug, PartialEq, Eq)] pub enum Chan { /// # — network-global channel, available from any server in the network. Global(ByteVec), /// & — 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) }