Parse chathistory command

This commit is contained in:
Mikhail 2024-05-28 19:25:31 +02:00
parent fac20a215d
commit b3d27e96c2
3 changed files with 58 additions and 3 deletions

View File

@ -30,7 +30,7 @@ impl Storage {
} }
#[tracing::instrument(skip(self), name = "Storage::retrieve_room_message_history")] #[tracing::instrument(skip(self), name = "Storage::retrieve_room_message_history")]
pub async fn get_room_message_history(&self, room_id: u32) -> Result<Vec<StoredMessage>> { pub async fn get_room_message_history(&self, room_id: u32, limit: u32) -> Result<Vec<StoredMessage>> {
let mut executor = self.conn.lock().await; let mut executor = self.conn.lock().await;
let res = sqlx::query_as( let res = sqlx::query_as(
" "
@ -47,10 +47,14 @@ impl Storage {
where where
room_id = ? room_id = ?
order by order by
messages.id; messages.id
--
limit ?;
", ",
// todo: implement limit
) )
.bind(room_id) .bind(room_id)
.bind(limit)
.fetch_all(&mut *executor) .fetch_all(&mut *executor)
.await?; .await?;

View File

@ -140,7 +140,7 @@ impl RegistrationState {
sender: Some(config.server_name.clone().into()), sender: Some(config.server_name.clone().into()),
body: ServerMessageBody::Cap { body: ServerMessageBody::Cap {
target: self.future_nickname.clone().unwrap_or_else(|| "*".into()), target: self.future_nickname.clone().unwrap_or_else(|| "*".into()),
subcmd: CapSubBody::Ls("sasl=PLAIN server-time".into()), subcmd: CapSubBody::Ls("sasl=PLAIN server-time draft/chathistory".into()),
}, },
} }
.write_async(writer) .write_async(writer)
@ -167,6 +167,13 @@ impl RegistrationState {
self.enabled_capabilities |= Capabilities::ServerTime; self.enabled_capabilities |= Capabilities::ServerTime;
} }
acked.push(cap); acked.push(cap);
} else if &*cap.name == "draft/chathistory" {
if cap.to_disable {
self.enabled_capabilities &= !Capabilities::ChatHistory;
} else {
self.enabled_capabilities |= Capabilities::ChatHistory;
}
acked.push(cap);
} else { } else {
naked.push(cap); naked.push(cap);
} }
@ -853,6 +860,8 @@ async fn handle_incoming_message(
log::info!("Received QUIT"); log::info!("Received QUIT");
return Ok(HandleResult::Leave); return Ok(HandleResult::Leave);
} }
// todo: implement chat history logic here.
// ClientMessage:ChatHistory { ... } => {}
cmd => { cmd => {
log::warn!("Not implemented handler for client command: {cmd:?}"); log::warn!("Not implemented handler for client command: {cmd:?}");
} }

View File

@ -65,6 +65,10 @@ pub enum ClientMessage {
reason: Str, reason: Str,
}, },
Authenticate(Str), Authenticate(Str),
Chathistory {
chan: Chan,
limit: u32,
},
} }
pub mod command_args { pub mod command_args {
@ -95,6 +99,7 @@ pub fn client_message(input: &str) -> Result<ClientMessage> {
client_message_privmsg, client_message_privmsg,
client_message_quit, client_message_quit,
client_message_authenticate, client_message_authenticate,
client_message_chathistory,
)))(input); )))(input);
match res { match res {
Ok((_, e)) => Ok(e), Ok((_, e)) => Ok(e),
@ -134,6 +139,7 @@ fn client_message_nick(input: &str) -> IResult<&str, ClientMessage> {
}, },
)) ))
} }
fn client_message_pass(input: &str) -> IResult<&str, ClientMessage> { fn client_message_pass(input: &str) -> IResult<&str, ClientMessage> {
let (input, _) = tag("PASS ")(input)?; let (input, _) = tag("PASS ")(input)?;
let (input, r) = opt(tag(":"))(input)?; let (input, r) = opt(tag(":"))(input)?;
@ -172,6 +178,7 @@ fn client_message_user(input: &str) -> IResult<&str, ClientMessage> {
}, },
)) ))
} }
fn client_message_join(input: &str) -> IResult<&str, ClientMessage> { fn client_message_join(input: &str) -> IResult<&str, ClientMessage> {
let (input, _) = tag("JOIN ")(input)?; let (input, _) = tag("JOIN ")(input)?;
let (input, chan) = chan(input)?; let (input, chan) = chan(input)?;
@ -280,6 +287,22 @@ fn client_message_authenticate(input: &str) -> IResult<&str, ClientMessage> {
Ok((input, ClientMessage::Authenticate(body.into()))) Ok((input, ClientMessage::Authenticate(body.into())))
} }
fn client_message_chathistory(input: &str) -> IResult<&str, ClientMessage> {
let (input, _) = tag("CHATHISTORY LATEST ")(input)?;
let (input, chan) = chan(input)?;
let (input, _) = tag(" * ")(input)?;
let (input, limit) = limit(input)?;
Ok((input, ClientMessage::Chathistory { chan, limit }))
}
fn limit(input: &str) -> IResult<&str, u32> {
let (input, limit) = receiver(input)?;
let limit = limit.parse().unwrap();
Ok((input, limit))
}
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum CapabilitySubcommand { pub enum CapabilitySubcommand {
/// CAP LS {code} /// CAP LS {code}
@ -383,6 +406,7 @@ mod test {
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result)); assert_matches!(result, Ok(result) => assert_eq!(expected, result));
} }
#[test] #[test]
fn test_client_message_pong() { fn test_client_message_pong() {
let input = "PONG 1337"; let input = "PONG 1337";
@ -391,6 +415,7 @@ mod test {
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result)); assert_matches!(result, Ok(result) => assert_eq!(expected, result));
} }
#[test] #[test]
fn test_client_message_nick() { fn test_client_message_nick() {
let input = "NICK SomeNick"; let input = "NICK SomeNick";
@ -401,6 +426,7 @@ mod test {
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result)); assert_matches!(result, Ok(result) => assert_eq!(expected, result));
} }
#[test] #[test]
fn test_client_message_whois() { fn test_client_message_whois() {
let test_user = "WHOIS val"; let test_user = "WHOIS val";
@ -461,6 +487,7 @@ mod test {
assert_matches!(res_more_than_two_params, Ok(result) => assert_eq!(expected_more_than_two_params, result)); assert_matches!(res_more_than_two_params, Ok(result) => assert_eq!(expected_more_than_two_params, result));
assert_matches!(res_none_none_params, Ok(result) => assert_eq!(expected_none_none_params, result)) assert_matches!(res_none_none_params, Ok(result) => assert_eq!(expected_none_none_params, result))
} }
#[test] #[test]
fn test_client_message_user() { fn test_client_message_user() {
let input = "USER SomeNick 8 * :Real Name"; let input = "USER SomeNick 8 * :Real Name";
@ -472,6 +499,7 @@ mod test {
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result)); assert_matches!(result, Ok(result) => assert_eq!(expected, result));
} }
#[test] #[test]
fn test_client_message_part() { fn test_client_message_part() {
let input = "PART #chan :Pokasiki !!!"; let input = "PART #chan :Pokasiki !!!";
@ -483,6 +511,7 @@ mod test {
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result)); assert_matches!(result, Ok(result) => assert_eq!(expected, result));
} }
#[test] #[test]
fn test_client_message_part_empty() { fn test_client_message_part_empty() {
let input = "PART #chan"; let input = "PART #chan";
@ -494,6 +523,7 @@ mod test {
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result)); assert_matches!(result, Ok(result) => assert_eq!(expected, result));
} }
#[test] #[test]
fn test_client_cap_req() { fn test_client_cap_req() {
let input = "CAP REQ :multi-prefix -sasl"; let input = "CAP REQ :multi-prefix -sasl";
@ -513,4 +543,16 @@ mod test {
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result)); assert_matches!(result, Ok(result) => assert_eq!(expected, result));
} }
#[test]
fn test_client_chat_history_latest() {
let input = "CHATHISTORY LATEST #chan * 10";
let expected = ClientMessage::Chathistory {
chan: Chan::Global("chan".into()),
limit: 10,
};
let result = client_message(input);
assert_matches!(result, Ok(result) => assert_eq!(expected, result));
}
} }