use anyhow::{Context, Result};
pub fn resolve_content_input(
inline: Option<&str>,
path: Option<&str>,
field: &str,
) -> Result<Option<String>> {
match (inline, path) {
(Some(_), Some(_)) => {
anyhow::bail!("Provide either `{field}` or `{field}_path`, not both.")
}
(Some(inline), None) => Ok(Some(inline.to_string())),
(None, Some(path)) => {
let body = std::fs::read_to_string(path)
.with_context(|| format!("Failed to read `{field}_path` file {path}"))?;
Ok(Some(body))
}
(None, None) => Ok(None),
}
}
pub fn require_content_input(
inline: Option<&str>,
path: Option<&str>,
field: &str,
) -> Result<String> {
resolve_content_input(inline, path, field)?
.ok_or_else(|| anyhow::anyhow!("Provide either `{field}` or `{field}_path`."))
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn resolve_returns_inline_when_only_inline_set() {
let got = resolve_content_input(Some("hello"), None, "content").unwrap();
assert_eq!(got.as_deref(), Some("hello"));
}
#[test]
fn resolve_reads_file_when_only_path_set() {
let tmp = tempfile::tempdir().unwrap();
let path = tmp.path().join("body.md");
std::fs::write(&path, "from disk").unwrap();
let got = resolve_content_input(None, Some(path.to_str().unwrap()), "content").unwrap();
assert_eq!(got.as_deref(), Some("from disk"));
}
#[test]
fn resolve_returns_none_when_neither_set() {
let got = resolve_content_input(None, None, "content").unwrap();
assert!(got.is_none());
}
#[test]
fn resolve_errors_when_both_set() {
let err = resolve_content_input(Some("a"), Some("/tmp/x"), "content").unwrap_err();
assert!(err
.to_string()
.contains("Provide either `content` or `content_path`, not both"));
}
#[test]
fn resolve_errors_with_field_name_in_message() {
let err = resolve_content_input(Some("a"), Some("/tmp/x"), "document").unwrap_err();
assert!(err.to_string().contains("`document` or `document_path`"));
}
#[test]
fn resolve_errors_when_path_missing() {
let err =
resolve_content_input(None, Some("/nonexistent_zxq/nope.md"), "content").unwrap_err();
assert!(err
.to_string()
.contains("Failed to read `content_path` file"));
}
#[test]
fn require_errors_when_neither_set() {
let err = require_content_input(None, None, "content").unwrap_err();
assert!(err
.to_string()
.contains("Provide either `content` or `content_path`."));
}
#[test]
fn require_returns_body_when_path_set() {
let tmp = tempfile::tempdir().unwrap();
let path = tmp.path().join("body.md");
std::fs::write(&path, "required body").unwrap();
let got = require_content_input(None, Some(path.to_str().unwrap()), "content").unwrap();
assert_eq!(got, "required body");
}
}