use crate::envelope;
use crate::error::{Error, Result};
use crate::google::docs::DocumentRef;
use crate::orgfile;
use crate::sexp::Sexp;
#[derive(Debug, Clone)]
pub struct OpenOutcome {
pub document_id: String,
pub url: String,
}
pub fn open(content: &str) -> Result<OpenOutcome> {
let document_id = orgfile::read_keyword(content, "GDOC_ID").ok_or(Error::NotLinked)?;
let url = orgfile::read_keyword(content, "GDOC_URL")
.unwrap_or_else(|| DocumentRef::from_id(document_id.clone()).url);
Ok(OpenOutcome { document_id, url })
}
#[must_use]
pub fn envelope(outcome: &OpenOutcome) -> Sexp {
envelope::ok(
"open",
vec![
("document-id", Sexp::string(outcome.document_id.clone())),
("url", Sexp::string(outcome.url.clone())),
],
)
}
#[cfg(test)]
mod tests {
use super::open;
use crate::error::Error;
#[test]
fn open_prefers_the_stored_url() {
let content =
"#+GDOC_ID: DOC1\n#+GDOC_URL: https://docs.google.com/document/d/DOC1/edit\n* Intro\n";
let outcome = open(content).expect("open succeeds");
assert_eq!(outcome.document_id, "DOC1");
assert_eq!(outcome.url, "https://docs.google.com/document/d/DOC1/edit");
}
#[test]
fn open_derives_url_when_only_id_is_present() {
let content = "#+GDOC_ID: ABC123\n* Intro\nbody\n";
let outcome = open(content).expect("open succeeds");
assert_eq!(
outcome.url,
"https://docs.google.com/document/d/ABC123/edit"
);
}
#[test]
fn open_without_a_linked_doc_is_not_linked_error() {
let content = "* Intro\nNo link here.\n";
assert!(matches!(open(content), Err(Error::NotLinked)));
}
}