imap_client/tasks/
resolver.rs1use imap_next::{
2 client::Client as ClientNext,
3 imap_types::response::{Response, Status},
4 Interrupt, State,
5};
6use tracing::{debug, warn};
7
8use super::{Scheduler, SchedulerError, SchedulerEvent, Task, TaskHandle};
9
10pub struct Resolver {
12 pub scheduler: Scheduler,
13}
14
15impl Resolver {
16 pub fn new(client_next: ClientNext) -> Self {
18 Self {
19 scheduler: Scheduler::new(client_next),
20 }
21 }
22
23 pub fn resolve<T: Task>(&mut self, task: T) -> ResolvingTask<T> {
25 let handle = self.scheduler.enqueue_task(task);
26
27 ResolvingTask {
28 resolver: self,
29 handle,
30 }
31 }
32}
33
34impl State for Resolver {
35 type Event = SchedulerEvent;
36 type Error = SchedulerError;
37
38 fn enqueue_input(&mut self, bytes: &[u8]) {
39 self.scheduler.enqueue_input(bytes);
40 }
41
42 fn next(&mut self) -> Result<Self::Event, Interrupt<Self::Error>> {
43 self.scheduler.progress()
44 }
45}
46
47pub struct ResolvingTask<'a, T: Task> {
48 resolver: &'a mut Resolver,
49 handle: TaskHandle<T>,
50}
51
52impl<T: Task> State for ResolvingTask<'_, T> {
53 type Event = T::Output;
54 type Error = SchedulerError;
55
56 fn enqueue_input(&mut self, bytes: &[u8]) {
57 self.resolver.enqueue_input(bytes);
58 }
59
60 fn next(&mut self) -> Result<Self::Event, Interrupt<Self::Error>> {
61 loop {
62 match self.resolver.next()? {
63 SchedulerEvent::GreetingReceived(greeting) => {
64 debug!("received greeting: {greeting:?}");
65 }
66 SchedulerEvent::TaskFinished(mut token) => {
67 if let Some(output) = self.handle.resolve(&mut token) {
68 break Ok(output);
69 } else {
70 warn!(?token, "received unexpected task token")
71 }
72 }
73 SchedulerEvent::Unsolicited(unsolicited) => {
74 if let Response::Status(Status::Bye(bye)) = unsolicited {
75 let err = SchedulerError::UnexpectedByeResponse(bye);
76 break Err(Interrupt::Error(err));
77 } else {
78 warn!(?unsolicited, "received unsolicited");
79 }
80 }
81 }
82 }
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use static_assertions::assert_impl_all;
89
90 use super::Resolver;
91
92 assert_impl_all!(Resolver: Send);
93}