1use serde::{Deserialize, Serialize};
4
5use crate::knowledge::Requester;
6use crate::{BoxError, async_trait};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[serde(rename_all = "kebab-case")]
11pub enum MemoryScope {
12 User,
14 Room,
16 Global,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct MemoryNote {
23 pub scope: MemoryScope,
25 pub title: Option<String>,
27 pub text: String,
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
33pub struct MemoryEntry {
34 pub id: String,
36 pub scope: MemoryScope,
38 pub title: String,
40 pub text: String,
42 pub author: Option<String>,
44 pub updated: String,
46}
47
48#[derive(Debug, thiserror::Error)]
50#[non_exhaustive]
51pub enum MemoryError {
52 #[error("no note `{0}` is visible here")]
54 NotFound(String),
55 #[error("not allowed: {0}")]
57 Forbidden(String),
58 #[error("{0}")]
60 Invalid(String),
61 #[error("memory storage: {0}")]
63 Backend(#[source] BoxError),
64}
65
66#[async_trait]
68pub trait MemoryStore: Send + Sync {
69 async fn save(&self, who: &Requester, note: MemoryNote) -> Result<MemoryEntry, MemoryError>;
71
72 async fn list(&self, who: &Requester) -> Result<Vec<MemoryEntry>, MemoryError>;
74
75 async fn forget(&self, who: &Requester, id: &str) -> Result<MemoryEntry, MemoryError>;
78
79 async fn note(
82 &self,
83 who: &Requester,
84 scope: MemoryScope,
85 text: &str,
86 ) -> Result<String, MemoryError> {
87 let _ = (who, scope, text);
88 Err(MemoryError::Invalid("this bot keeps no journal".into()))
89 }
90}