#![allow(dead_code)]
use std::error::Error;
use std::fs;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU32, Ordering};
pub const BLOCK: usize = 2880;
pub const CARD: usize = 80;
pub fn card(keyword: &str, value: &str) -> String {
let card = format!("{:<8}= {:>20}", keyword, value);
let card = format!("{:<width$}", card, width = CARD);
debug_assert_eq!(card.len(), CARD, "card {:?} does not fit", keyword);
card
}
pub fn fits_file(cards: &[(&str, &str)], data: &[u8]) -> Vec<u8> {
let mut header = String::new();
for (keyword, value) in cards {
header.push_str(&card(keyword, value));
}
header.push_str(&format!("{:<80}", "END"));
let mut bytes = header.into_bytes();
pad_to_block(&mut bytes, b' ');
bytes.extend_from_slice(data);
pad_to_block(&mut bytes, 0);
bytes
}
pub fn append_extension(file: &mut Vec<u8>, cards: &[(&str, &str)], data: &[u8]) {
file.extend_from_slice(&fits_file(cards, data));
}
fn pad_to_block(bytes: &mut Vec<u8>, filler: u8) {
let padding = (BLOCK - bytes.len() % BLOCK) % BLOCK;
bytes.resize(bytes.len() + padding, filler);
}
pub fn fixture(name: &str) -> Option<PathBuf> {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join(name);
match fs::metadata(&path) {
Ok(metadata) if metadata.len() > 4096 => Some(path),
_ => {
eprintln!("skipping: fixture {name} is not present (run `git lfs pull`)");
None
}
}
}
pub fn write_temp_fits(
name: &str,
contents: &[u8],
) -> Result<PathBuf, Box<dyn Error + Send + Sync>> {
static COUNTER: AtomicU32 = AtomicU32::new(0);
let directory = std::env::temp_dir().join(format!(
"fits-io-test-{}-{}",
std::process::id(),
COUNTER.fetch_add(1, Ordering::Relaxed)
));
fs::create_dir_all(&directory)?;
let path = directory.join(name);
fs::write(&path, contents)?;
Ok(path)
}