use crate::CoreError;
use camino::{Utf8Path, Utf8PathBuf};
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RecipeSource {
Path(Utf8PathBuf),
Content {
text: String,
name: String,
},
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub enum ConfigSource {
Path(Utf8PathBuf),
Inline(String),
#[default]
None,
}
impl ConfigSource {
pub fn read(&self) -> Result<Option<String>, CoreError> {
match self {
ConfigSource::None => Ok(None),
ConfigSource::Inline(text) => Ok(Some(text.clone())),
ConfigSource::Path(path) => match std::fs::read_to_string(path) {
Ok(text) => Ok(Some(text)),
Err(source) => Err(CoreError::Io {
path: path.clone(),
source,
}),
},
}
}
pub fn is_unset(&self) -> bool {
matches!(self, ConfigSource::None)
}
pub fn path(&self) -> Option<&Utf8Path> {
match self {
ConfigSource::Path(p) => Some(p),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn none_reads_as_none() {
assert!(ConfigSource::None.read().unwrap().is_none());
assert!(ConfigSource::None.is_unset());
}
#[test]
fn inline_reads_its_text() {
let source = ConfigSource::Inline("[produce]\ntomato".to_string());
assert_eq!(source.read().unwrap().as_deref(), Some("[produce]\ntomato"));
assert!(!source.is_unset());
assert_eq!(source.path(), None);
}
#[test]
fn path_reads_from_disk() {
let dir = tempfile::TempDir::new().unwrap();
let path = dir.path().join("aisle.conf");
std::fs::write(&path, "[dairy]\nmilk").unwrap();
let utf8 = camino::Utf8PathBuf::from_path_buf(path).unwrap();
let source = ConfigSource::Path(utf8.clone());
assert_eq!(source.read().unwrap().as_deref(), Some("[dairy]\nmilk"));
assert_eq!(source.path(), Some(utf8.as_path()));
}
#[test]
fn missing_path_is_an_io_error_naming_the_path() {
let missing = camino::Utf8PathBuf::from("/nonexistent/aisle.conf");
let source = ConfigSource::Path(missing.clone());
match source.read() {
Err(CoreError::Io { path, source }) => {
assert_eq!(path, missing);
assert_eq!(source.kind(), std::io::ErrorKind::NotFound);
}
other => panic!("expected CoreError::Io, got {other:?}"),
}
}
}