Skip to main content

fits_header/
lib.rs

1//! # fits-header
2//!
3//! A pure-Rust, MSVC-safe library for reading and writing the header of a
4//! [FITS](https://fits.gsfc.nasa.gov/fits_standard.html) file.
5//!
6//! It reads a header unit into an ordered [`Header`] of records, retaining every card so untouched
7//! cards serialize byte-for-byte and only created or modified cards are re-rendered. Access is
8//! strict and keyword-oriented: [`Header::get`] and friends take a [`Key`] that is either a bare
9//! name (unique-or-[`FitsError::AmbiguousKeyword`]) or `(name, occurrence)`. Values read through a
10//! generic [`FromCard`] and write through [`IntoValue`]; batch edits are atomic; long strings use
11//! the `CONTINUE` convention.
12//!
13//! ```
14//! use fits_header::{Header, StructuralHints};
15//!
16//! let mut h = Header::new();
17//! h.set("OBJECT", "M31").unwrap();
18//! h.set("EXPTIME", 120.0).unwrap();
19//! assert_eq!(h.get::<f64>("EXPTIME").unwrap(), Some(120.0));
20//!
21//! let bytes = h.to_bytes(&StructuralHints::default()).unwrap();
22//! assert_eq!(bytes.len() % fits_header::BLOCK_LEN, 0);
23//! ```
24//!
25//! ## Design
26//!
27//! - Pure Rust, no C or system libraries; builds with the MSVC toolchain.
28//! - An untouched card (and untouched long-string run) re-emits identical bytes.
29//! - Ambiguous keyword access errors instead of guessing.
30//!
31//! ## Features
32//!
33//! - `serde` *(off)* — derive `Serialize`/`Deserialize` on the public types.
34//! - `coords` *(off)* — sexagesimal RA/Dec and MJD↔calendar helpers.
35#![forbid(unsafe_code)]
36
37mod dates;
38mod error;
39mod header;
40mod key;
41mod parse;
42mod record;
43mod value;
44mod write;
45
46#[cfg(feature = "coords")]
47mod coords;
48
49/// Bytes per header card.
50pub const CARD_LEN: usize = 80;
51/// Bytes per FITS block (36 cards).
52pub const BLOCK_LEN: usize = 2880;
53
54pub use crate::dates::{format_datetime, parse_datetime};
55pub use crate::error::FitsError;
56pub use crate::header::Header;
57pub use crate::key::Key;
58pub use crate::parse::parse;
59pub use crate::record::{Record, RecordKind, Value};
60pub use crate::value::{parse_f64, parse_i64, Fixed, FromCard, IntoValue, Literal, Sci};
61pub use crate::write::{StructuralHints, MAX_ZERO_FILL};
62
63#[cfg(feature = "coords")]
64pub use crate::coords::{
65    deg_to_sexagesimal_dec, deg_to_sexagesimal_ra, sexagesimal_dec_to_deg, sexagesimal_ra_to_deg,
66};
67#[cfg(feature = "coords")]
68pub use crate::dates::{datetime_to_mjd, mjd_to_datetime};
69
70/// Compiles the README's code blocks as doctests so the documented API cannot drift.
71#[cfg(doctest)]
72#[doc = include_str!("../README.md")]
73struct ReadmeDoctests;