forked from lavina/lavina
52 lines
1.3 KiB
Rust
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)
|
|
}
|