1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! The journal entry a day holds, read and written as its content.
//!
//! A day has at most one entry. HEY answers it as a calendar recording carrying the full
//! text (`content`) and the rich-text HTML (`content_html`); a day with no entry answers
//! 204 and no body, which reads here as `None`.
use crate::error::Error;
use crate::generated::routes;
use crate::generated::types::{JournalEntryPayload, Recording, UpdateJournalEntryRequestContent};
use crate::operation::Operation;
pub use crate::generated::services::journal::*;
impl Journal<'_> {
/// The rich-text HTML of the day's journal entry, falling back to its plain text, or
/// `None` when the day has no entry. `day` is `YYYY-MM-DD`.
///
/// The fallback covers an empty `content_html` as well as a missing one: HEY serves the
/// key blank on an entry it has no rendered body for, and blank is not the entry.
pub async fn get_content(&self, day: &str) -> Result<Option<String>, Error> {
let mut operation = self.client().operation(&routes::GET_JOURNAL_ENTRY, &[&day]);
operation.operation_name("GetJournalContent");
let entry = self.recording(operation).await?;
Ok(entry.and_then(|entry| {
entry
.content_html
.filter(|html| !html.is_empty())
.or(entry.content)
}))
}
/// The day's journal entry, or `None` when it has none. The generated
/// [`Journal::get_entry`] reads the same route but takes the empty answer for a day
/// without an entry as a body it could not decode.
pub async fn entry(&self, day: &str) -> Result<Option<Recording>, Error> {
let operation = self.client().operation(&routes::GET_JOURNAL_ENTRY, &[&day]);
self.recording(operation).await
}
/// Writes the day's journal entry, creating it if needed, and answers it as a
/// recording. Empty content removes the entry, which HEY answers with nothing, so the
/// result is `None`.
pub async fn update_content(
&self,
day: &str,
content: &str,
) -> Result<Option<Recording>, Error> {
let body = UpdateJournalEntryRequestContent {
calendar_journal_entry: JournalEntryPayload {
content: content.to_string(),
},
};
let mut operation = self
.client()
.operation(&routes::UPDATE_JOURNAL_ENTRY, &[&day]);
operation.json(&body)?;
self.recording(operation).await
}
async fn recording(&self, operation: Operation) -> Result<Option<Recording>, Error> {
let response = self.client().execute(operation).await?;
if response.body.is_empty() {
Ok(None)
} else {
response.json().map(Some)
}
}
}