use crate::Error;
use std::io::Read;
fn split_spec(spec: &str) -> (&str, Option<&str>) {
if let Some(idx) = spec.find('#') {
(&spec[..idx], Some(&spec[idx + 1..]))
} else {
(spec, None)
}
}
pub fn resolve_seed_input(spec: &str) -> Result<Vec<u8>, Error> {
let (path, suffix) = split_spec(spec);
let file_bytes = if path == "-" {
let stdin = std::io::stdin();
let mut handle = stdin.lock();
let mut buf = Vec::new();
handle.read_to_end(&mut buf)?;
buf
} else {
std::fs::read(path).map_err(|_| Error::SeedSourceUnavailable(path.to_string()))?
};
let mut out = file_bytes;
if let Some(suffix) = suffix {
out.push(b'#');
out.extend_from_slice(suffix.as_bytes());
}
Ok(out)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn split_spec_no_suffix() {
assert_eq!(split_spec("/tmp/foo"), ("/tmp/foo", None));
}
#[test]
fn split_spec_with_suffix() {
assert_eq!(split_spec("/tmp/foo#bar"), ("/tmp/foo", Some("bar")));
}
#[test]
fn split_spec_empty_suffix() {
assert_eq!(split_spec("/tmp/foo#"), ("/tmp/foo", Some("")));
}
#[test]
fn resolve_missing_file_returns_seed_unavailable() {
let result = resolve_seed_input("/tmp/definitely-not-a-real-file-xyz-789");
match result {
Err(Error::SeedSourceUnavailable(p)) => {
assert!(p.contains("definitely-not-a-real-file"));
}
other => panic!("expected SeedSourceUnavailable, got {other:?}"),
}
}
#[test]
fn resolve_with_suffix_appends_hash_and_suffix() {
let tmpdir = tempfile::tempdir().unwrap();
let path = tmpdir.path().join("seed.txt");
std::fs::write(&path, b"hello").unwrap();
let spec = format!("{}#world", path.display());
let bytes = resolve_seed_input(&spec).unwrap();
assert_eq!(bytes, b"hello#world");
}
#[test]
fn resolve_without_suffix_returns_raw_file_bytes() {
let tmpdir = tempfile::tempdir().unwrap();
let path = tmpdir.path().join("seed.txt");
std::fs::write(&path, b"raw-bytes").unwrap();
let bytes = resolve_seed_input(&path.to_string_lossy()).unwrap();
assert_eq!(bytes, b"raw-bytes");
}
}