forked from lavina/lavina
add support for additional irc messages types
This commit is contained in:
parent
e5d0722fe0
commit
5d57df3219
|
@ -7,13 +7,25 @@ pub enum ClientMessage {
|
|||
Capability {
|
||||
subcommand: CapabilitySubcommand,
|
||||
},
|
||||
/// PING
|
||||
/// PING <token>
|
||||
Ping {
|
||||
token: ByteVec,
|
||||
},
|
||||
/// PONG <token>
|
||||
Pong {
|
||||
token: ByteVec,
|
||||
},
|
||||
/// NICK <name>
|
||||
Nick {
|
||||
nickname: ByteVec,
|
||||
},
|
||||
User {
|
||||
username: ByteVec,
|
||||
realname: ByteVec,
|
||||
},
|
||||
Quit {
|
||||
reason: ByteVec,
|
||||
},
|
||||
}
|
||||
|
||||
pub fn client_message(input: &[u8]) -> IResult<&[u8], ClientMessage> {
|
||||
|
@ -21,6 +33,9 @@ pub fn client_message(input: &[u8]) -> IResult<&[u8], ClientMessage> {
|
|||
client_message_capability,
|
||||
client_message_ping,
|
||||
client_message_pong,
|
||||
client_message_nick,
|
||||
client_message_user,
|
||||
client_message_quit,
|
||||
))(input)
|
||||
}
|
||||
|
||||
|
@ -55,6 +70,47 @@ fn client_message_pong(input: &[u8]) -> IResult<&[u8], ClientMessage> {
|
|||
))
|
||||
}
|
||||
|
||||
fn client_message_nick(input: &[u8]) -> IResult<&[u8], ClientMessage> {
|
||||
let (input, _) = tag("NICK ")(input)?;
|
||||
let (input, nickname) = receiver(input)?;
|
||||
|
||||
Ok((
|
||||
input,
|
||||
ClientMessage::Nick {
|
||||
nickname: nickname.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn client_message_user(input: &[u8]) -> IResult<&[u8], ClientMessage> {
|
||||
let (input, _) = tag("USER ")(input)?;
|
||||
let (input, username) = receiver(input)?;
|
||||
let (input, _) = tag(" ")(input)?;
|
||||
let (input, _) = take(1_usize)(input)?; // 0 in spec, but any in fact
|
||||
let (input, _) = tag(" * :")(input)?;
|
||||
let (input, realname) = token(input)?;
|
||||
|
||||
Ok((
|
||||
input,
|
||||
ClientMessage::User {
|
||||
username: username.to_owned(),
|
||||
realname: realname.to_owned(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn client_message_quit(input: &[u8]) -> IResult<&[u8], ClientMessage> {
|
||||
let (input, _) = tag("QUIT :")(input)?;
|
||||
let (input, reason) = token(input)?;
|
||||
|
||||
Ok((
|
||||
input,
|
||||
ClientMessage::Quit {
|
||||
reason: reason.to_vec(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum CapabilitySubcommand {
|
||||
/// CAP LS {code}
|
||||
|
@ -128,6 +184,27 @@ mod test {
|
|||
token: b"1337".to_vec(),
|
||||
};
|
||||
|
||||
let result = client_message(input);
|
||||
assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
|
||||
}
|
||||
#[test]
|
||||
fn test_client_message_nick() {
|
||||
let input = b"NICK SomeNick";
|
||||
let expected = ClientMessage::Nick {
|
||||
nickname: b"SomeNick".to_vec(),
|
||||
};
|
||||
|
||||
let result = client_message(input);
|
||||
assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
|
||||
}
|
||||
#[test]
|
||||
fn test_client_message_user() {
|
||||
let input = b"USER SomeNick 8 * :Real Name";
|
||||
let expected = ClientMessage::User {
|
||||
username: b"SomeNick".to_vec(),
|
||||
realname: b"Real Name".to_vec(),
|
||||
};
|
||||
|
||||
let result = client_message(input);
|
||||
assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
|
||||
}
|
||||
|
|
|
@ -26,3 +26,26 @@ fn receiver(input: &[u8]) -> IResult<&[u8], &[u8]> {
|
|||
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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue