use std::io::Write;
#[cfg(not(feature = "quirk_crlf_relaxed"))]
use abnf_core::streaming::crlf;
#[cfg(feature = "quirk_crlf_relaxed")]
use abnf_core::streaming::crlf_relaxed as crlf;
use imap_types::{command::CommandBody, extensions::idle::IdleDone};
use nom::{bytes::streaming::tag_no_case, combinator::value, sequence::tuple};
use crate::{
decode::IMAPResult,
encode::{EncodeContext, EncodeIntoContext},
};
pub(crate) fn idle(input: &[u8]) -> IMAPResult<&[u8], CommandBody> {
value(CommandBody::Idle, tag_no_case("IDLE"))(input)
}
pub(crate) fn idle_done(input: &[u8]) -> IMAPResult<&[u8], IdleDone> {
value(IdleDone, tuple((tag_no_case("DONE"), crlf)))(input)
}
impl EncodeIntoContext for IdleDone {
fn encode_ctx(&self, ctx: &mut EncodeContext) -> std::io::Result<()> {
ctx.write_all(b"DONE\r\n")
}
}
#[cfg(test)]
mod tests {
use imap_types::command::{Command, CommandBody};
use super::*;
use crate::{
decode::{Decoder, IdleDoneDecodeError},
testing::kat_inverse_command,
IdleDoneCodec,
};
#[test]
fn test_kat_inverse_command_idle() {
kat_inverse_command(&[
(
b"A IDLE\r\n".as_ref(),
b"".as_ref(),
Command::new("A", CommandBody::Idle).unwrap(),
),
(
b"A IDLE\r\n?",
b"?",
Command::new("A", CommandBody::Idle).unwrap(),
),
]);
}
#[test]
fn test_decode_idle_done() {
let tests = [
(b"done\r\n".as_ref(), Ok((b"".as_ref(), IdleDone))),
(b"done\r\n?".as_ref(), Ok((b"?".as_ref(), IdleDone))),
(b"d".as_ref(), Err(IdleDoneDecodeError::Incomplete)),
(b"do".as_ref(), Err(IdleDoneDecodeError::Incomplete)),
(b"don".as_ref(), Err(IdleDoneDecodeError::Incomplete)),
(b"done".as_ref(), Err(IdleDoneDecodeError::Incomplete)),
(b"done\r".as_ref(), Err(IdleDoneDecodeError::Incomplete)),
(b"donee\r\n".as_ref(), Err(IdleDoneDecodeError::Failed)),
(b" done\r\n".as_ref(), Err(IdleDoneDecodeError::Failed)),
(b"done \r\n".as_ref(), Err(IdleDoneDecodeError::Failed)),
(b" done \r\n".as_ref(), Err(IdleDoneDecodeError::Failed)),
];
for (test, expected) in tests {
let got = IdleDoneCodec::default().decode(test);
dbg!((std::str::from_utf8(test).unwrap(), &expected, &got));
assert_eq!(expected, got);
}
}
}