use crate::MacosError;
use crate::applescript::{escape, escape_body, run};
pub fn create_note(title: &str, body: &str, folder: &str) -> Result<(), MacosError> {
let escaped_title = escape(title);
let escaped_folder = escape(folder);
let body_expr = escape_body(body);
let script = format!(
r#"
tell application "Notes"
try
set targetFolder to folder "{escaped_folder}"
on error
make new folder with properties {{name:"{escaped_folder}"}}
set targetFolder to folder "{escaped_folder}"
end try
make new note at targetFolder with properties {{name:"{escaped_title}", body:{body_expr}}}
end tell
"#
);
run(&script, "failed to create note")
}
pub fn update_note(title: &str, body: &str, folder: &str) -> Result<(), MacosError> {
let escaped_title = escape(title);
let escaped_folder = escape(folder);
let body_expr = escape_body(body);
let script = format!(
r#"
tell application "Notes"
set theNote to (first note of folder "{escaped_folder}" whose name is "{escaped_title}")
set body of theNote to {body_expr}
set name of theNote to "{escaped_title}"
end tell
"#
);
run(&script, "failed to update note")
}
pub fn delete_note(title: &str, folder: &str) -> Result<(), MacosError> {
let escaped_title = escape(title);
let escaped_folder = escape(folder);
let script = format!(
r#"
tell application "Notes"
delete (first note of folder "{escaped_folder}" whose name is "{escaped_title}")
end tell
"#
);
run(&script, "failed to delete note")
}
pub fn move_note(title: &str, from_folder: &str, to_folder: &str) -> Result<(), MacosError> {
let escaped_title = escape(title);
let escaped_from = escape(from_folder);
let escaped_to = escape(to_folder);
let script = format!(
r#"
tell application "Notes"
try
set destFolder to folder "{escaped_to}"
on error
make new folder with properties {{name:"{escaped_to}"}}
set destFolder to folder "{escaped_to}"
end try
set theNote to (first note of folder "{escaped_from}" whose name is "{escaped_title}")
move theNote to destFolder
end tell
"#
);
run(&script, "failed to move note")
}
#[cfg(test)]
mod tests {
use super::{create_note, delete_note};
use std::time::{SystemTime, UNIX_EPOCH};
#[test]
#[ignore = "requires explicit authorization to create and delete a note in the real Notes app"]
fn create_note_supports_multiline_body() {
let suffix = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("clock should be after unix epoch")
.as_nanos();
let title = format!("Cueward create note multiline test {suffix}");
let folder = "Cueward";
let result = create_note(&title, "line1\nline2", folder);
let _ = delete_note(&title, folder);
assert!(
result.is_ok(),
"expected multiline note creation to succeed: {result:?}"
);
}
}