Skip to main content

rig_core/conversation/
note.rs

1//! Notes in a transcript ([`Note`]).
2
3use serde::{Deserialize, Serialize};
4
5use super::{Aside, Author, MessageId};
6
7/// A note in a transcript: an [`Aside`] of kind [`Note::KIND`] that every
8/// front showing the conversation draws after the entry it follows, with
9/// what it shows collapsed, in a line, and what it shows expanded. It never
10/// reaches a model, and it is saved, restored and forked with the
11/// conversation; one made [`unsaved`](Aside::unsaved) is not saved.
12///
13/// ```
14/// use rig_core::conversation::{Author, Conversation, Note};
15/// use rig_core::message::Message;
16///
17/// let mut conversation = Conversation::new();
18/// conversation.push(Message::user("Why tabs?"));
19/// let after = conversation.id(0);
20/// let note = Note::new("Why tabs?", "The project's style says so.");
21/// conversation.add_aside(note.aside(Author::plugin("btw"), after));
22/// ```
23#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
24pub struct Note {
25    /// What it shows collapsed, in a line.
26    pub title: String,
27    /// What it shows expanded.
28    pub text: String,
29}
30
31impl Note {
32    /// The kind of the asides that hold a note.
33    pub const KIND: &'static str = "note";
34
35    /// A note titled `title`, showing `text` expanded.
36    pub fn new(title: impl Into<String>, text: impl Into<String>) -> Self {
37        Self {
38            title: title.into(),
39            text: text.into(),
40        }
41    }
42
43    /// The saved aside by `author` that holds this note, following the
44    /// entry `after` (`None`: before the first).
45    pub fn aside(self, author: Author, after: Option<MessageId>) -> Aside {
46        let value = serde_json::json!({ "title": self.title, "text": self.text });
47        Aside::new(Self::KIND, author, value).after(after)
48    }
49
50    /// The note `aside` holds, when it holds one.
51    pub fn of(aside: &Aside) -> Option<Self> {
52        if aside.kind != Self::KIND {
53            return None;
54        }
55        Self::deserialize(&aside.value).ok()
56    }
57}