m4a_agent/backend/
attached.rs1use std::time::Duration;
7
8use mail4agent_messenger::{HttpResponseDescriptor, OutgoingRequest};
9
10use super::live::Live;
11use super::{Backend, BackendKind, Capabilities, Session};
12use crate::engine::{HttpExec, News};
13use crate::error::{AgentError, Result};
14use crate::identity::{IdentityStore, SessionIdentity};
15
16pub struct AttachedBackend {
17 kind: BackendKind,
18 base: String,
19 live: Live,
20 #[cfg(feature = "tier-matrix")]
21 sliding: super::sliding::Sliding,
22}
23
24impl AttachedBackend {
25 pub fn new(kind: BackendKind, base: &str, token: &str) -> Result<Self> {
27 let mut exec = HttpExec::new(base)?;
28 exec.probe_prefix();
29 Self::from_exec(kind, base, token, exec)
30 }
31
32 pub fn with_prefix(kind: BackendKind, base: &str, token: &str, keep_prefix: bool) -> Result<Self> {
35 let mut exec = HttpExec::new(base)?;
36 exec.set_keep_prefix(keep_prefix);
37 let me = Self::from_exec(kind, base, token, exec)?;
38 #[cfg(feature = "tier-matrix")]
39 me.sliding.set_mode(super::matrix::SyncMode::V3);
40 #[cfg(feature = "tier-matrix")]
41 me.sliding.decide(&me.live);
42 Ok(me)
43 }
44
45 fn from_exec(kind: BackendKind, base: &str, token: &str, exec: HttpExec) -> Result<Self> {
46 let live = Live::new(exec);
47 live.set_token(token);
48 let me = Self {
49 kind,
50 base: base.trim_end_matches('/').to_string(),
51 live,
52 #[cfg(feature = "tier-matrix")]
53 sliding: super::sliding::Sliding::new(),
54 };
55 #[cfg(feature = "tier-matrix")]
56 if kind == BackendKind::Matrix {
57 me.sliding.decide(&me.live);
58 }
59 Ok(me)
60 }
61
62 #[cfg(feature = "tier-matrix")]
64 pub fn without_sliding_sync(self) -> Self {
65 self.sliding.set_mode(super::matrix::SyncMode::V3);
66 self.sliding.decide(&self.live);
67 self
68 }
69
70 #[cfg(feature = "tier-matrix")]
71 pub fn uses_sliding_sync(&self) -> bool {
72 self.sliding.active()
73 }
74}
75
76impl Backend for AttachedBackend {
77 fn kind(&self) -> BackendKind {
78 self.kind
79 }
80 fn capabilities(&self) -> Capabilities {
81 Capabilities { rooms: self.kind == BackendKind::Matrix, federation: self.kind == BackendKind::Matrix }
82 }
83 fn server_ref(&self) -> &str {
84 &self.base
85 }
86 fn ensure_session(&self, _: &IdentityStore, _: &mut SessionIdentity, _: Option<&str>) -> Result<Session> {
87 Err(AgentError::Identity("this backend was handed an established session and cannot log in".into()))
88 }
89 fn execute(&self, request: &OutgoingRequest) -> Result<HttpResponseDescriptor> {
90 #[cfg(feature = "tier-matrix")]
91 if request.kind == mail4agent_messenger::OutgoingRequestKind::Sync {
92 if let Some(answer) = self.sliding.sync(&self.live, request)? {
93 return Ok(answer);
94 }
95 }
96 self.live.execute(request)
97 }
98 fn whoami(&self) -> Result<(String, String)> {
99 self.live.whoami()
100 }
101 fn keep_prefix(&self) -> bool {
102 self.live.keep_prefix()
103 }
104 fn wait_for_news(&self, timeout: Duration) -> Result<News> {
105 self.live.wait_for_news(timeout)
106 }
107}