From 3aca7df9972067acc7c9bbd3601b8a5d9a0507de Mon Sep 17 00:00:00 2001 From: Matthieu Baumann Date: Mon, 6 Jan 2025 14:58:43 +0100 Subject: [PATCH] Remove usage of nom crate + fix typo from https://github.com/cds-astro/fitsrs/issues/8 --- Cargo.toml | 3 +- README.md | 23 +++++++++++-- fitswasm/README.md | 2 +- src/card.rs | 11 ------- src/error.rs | 4 --- src/hdu/header/extension/bintable.rs | 49 +++++++++++++--------------- src/lib.rs | 1 - 7 files changed, 46 insertions(+), 47 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2889d07..d00e54d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fitsrs" -version = "0.2.11" +version = "0.2.12" authors = ["Matthieu Baumann "] edition = "2018" description = "Implementation of the FITS image parser" @@ -18,7 +18,6 @@ exclude = [ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -nom = "7.1.1" byteorder = "1.4.2" serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0" diff --git a/README.md b/README.md index e62d7ac..6402951 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -Fits reader written in pure Rust using [nom](https://github.com/Geal/nom) -------------------------------------------------------------------------- +Fits reader written in pure Rust +-------------------------------- [![](https://img.shields.io/crates/v/fitsrs.svg)](https://crates.io/crates/fitsrs) [![](https://img.shields.io/crates/d/fitsrs.svg)](https://crates.io/crates/fitsrs) @@ -12,6 +12,24 @@ This fits parser only supports image data (not tables), and does not know anythi For WCS parsing, see [wcsrs](https://github.com/cds-astro/wcs-rs). This parser is able to parse extension HDUs. Ascii tables and binary tables are still not properly parsed, only the list bytes of their data block can be retrieved but no interpretation/parsing is done on it. +Contributing +------------ + +> [!WARNING] +> Running the test involves test files you can download [here](https://alasky.cds.unistra.fr/Aladin-Lite-test-files/fits-rs-test-files.tar). This tar is 2.2GB. + +Once the tar file has been downloaded, put it into the root on your cloned repo and extract it: + +```bash +tar -xvf fits-rs-test-files.tar +``` + +Once the files have been extracted you can run the tests locally: + +```bash +cargo test --release +``` + To Do list ---------- @@ -20,6 +38,7 @@ To Do list * [X] Support big fits file parsing that may not fit in memory (iterator usage) * [X] Async reading (experimental and not tested) * [ ] Keep CARD comment +* [ ] Support compressed fits files (https://fits.gsfc.nasa.gov/registry/tilecompression.html) * [ ] Support data table (each column can have a specific types) * [X] Support of multiple HDU, fits extensions (in progress, only the header is parsed) * [ ] WCS parsing, see [wcsrs](https://github.com/cds-astro/wcs-rs) diff --git a/fitswasm/README.md b/fitswasm/README.md index 3df5ae9..eec593d 100644 --- a/fitswasm/README.md +++ b/fitswasm/README.md @@ -1,4 +1,4 @@ -# FITS reader written in pure Rust using [nom](https://github.com/Geal/nom) +# FITS reader written in pure Rust ## Install with npm diff --git a/src/card.rs b/src/card.rs index ff4308f..1df6864 100644 --- a/src/card.rs +++ b/src/card.rs @@ -1,12 +1,5 @@ use std::string::FromUtf8Error; -use nom::{ - character::complete::{i64, space0}, - combinator::map, - sequence::preceded, - IResult, -}; - use crate::error::Error; pub type Keyword = [u8; 8]; @@ -93,10 +86,6 @@ impl Value { } } -pub(crate) fn parse_integer(buf: &[u8]) -> IResult<&[u8], Value> { - preceded(space0, map(i64, |val| Value::Integer(val)))(buf) -} - #[cfg(test)] mod tests { use super::{Card, Value}; diff --git a/src/error.rs b/src/error.rs index 621e334..7424cd3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -25,10 +25,6 @@ quick_error! { NotSupportedXtensionType(extension: String) { display("`{}` extension is not supported. Only BINTABLE, TABLE and IMAGE are.", extension) } - Nom { - from(nom::Err>) - display("Nom could not parse header values") - } Utf8 { from(std::str::Utf8Error) display("Fail to parse a keyword as a utf8 string") diff --git a/src/hdu/header/extension/bintable.rs b/src/hdu/header/extension/bintable.rs index 22c2ef2..337cc56 100644 --- a/src/hdu/header/extension/bintable.rs +++ b/src/hdu/header/extension/bintable.rs @@ -4,14 +4,12 @@ use std::io::Read; use async_trait::async_trait; use futures::AsyncRead; -use nom::AsChar; use serde::Serialize; use crate::error::Error; use crate::hdu::header::consume_next_card_async; use crate::hdu::header::parse_bitpix_card; use crate::hdu::header::parse_gcount_card; -use crate::hdu::header::parse_integer; use crate::hdu::header::parse_naxis_card; use crate::hdu::header::parse_pcount_card; use crate::hdu::header::BitpixValue; @@ -71,30 +69,29 @@ impl Xtension for BinTable { .clone() .check_for_string()?; - let (field_type_char, repeat_count) = - if let Ok((remaining_bytes, Value::Integer(repeat_count))) = - parse_integer(card_value.as_bytes()) - { - (remaining_bytes[0].as_char(), repeat_count) - } else { - (owned_kw[0].as_char(), 1) - }; - let repeat_count = repeat_count as u64; - - match field_type_char.as_char() { - 'L' => Ok(TFormBinaryTableType::L(TFormBinaryTable::new(repeat_count))), // Logical - 'X' => Ok(TFormBinaryTableType::X(TFormBinaryTable::new(repeat_count))), // Bit - 'B' => Ok(TFormBinaryTableType::B(TFormBinaryTable::new(repeat_count))), // Unsigned Byte - 'I' => Ok(TFormBinaryTableType::I(TFormBinaryTable::new(repeat_count))), // 16-bit integer - 'J' => Ok(TFormBinaryTableType::J(TFormBinaryTable::new(repeat_count))), // 32-bit integer - 'K' => Ok(TFormBinaryTableType::K(TFormBinaryTable::new(repeat_count))), // 64-bit integer - 'A' => Ok(TFormBinaryTableType::A(TFormBinaryTable::new(repeat_count))), // Character - 'E' => Ok(TFormBinaryTableType::E(TFormBinaryTable::new(repeat_count))), // Single-precision floating point - 'D' => Ok(TFormBinaryTableType::D(TFormBinaryTable::new(repeat_count))), // Double-precision floating point - 'C' => Ok(TFormBinaryTableType::C(TFormBinaryTable::new(repeat_count))), // Single-precision complex - 'M' => Ok(TFormBinaryTableType::M(TFormBinaryTable::new(repeat_count))), // Double-precision complex - 'P' => Ok(TFormBinaryTableType::P(TFormBinaryTable::new(repeat_count))), // Array Descriptor (32-bit) - 'Q' => Ok(TFormBinaryTableType::Q(TFormBinaryTable::new(repeat_count))), // Array Descriptor (64-bit) + let count = card_value + .chars() + .take_while(|c| c.is_digit(10)) + .collect::(); + + let num_count_digits = count.len(); + let count = count.parse::().unwrap_or(1) as u64; + let field_ty = card_value.chars().nth(num_count_digits).unwrap(); + + match field_ty as char { + 'L' => Ok(TFormBinaryTableType::L(TFormBinaryTable::new(count))), // Logical + 'X' => Ok(TFormBinaryTableType::X(TFormBinaryTable::new(count))), // Bit + 'B' => Ok(TFormBinaryTableType::B(TFormBinaryTable::new(count))), // Unsigned Byte + 'I' => Ok(TFormBinaryTableType::I(TFormBinaryTable::new(count))), // 16-bit integer + 'J' => Ok(TFormBinaryTableType::J(TFormBinaryTable::new(count))), // 32-bit integer + 'K' => Ok(TFormBinaryTableType::K(TFormBinaryTable::new(count))), // 64-bit integer + 'A' => Ok(TFormBinaryTableType::A(TFormBinaryTable::new(count))), // Character + 'E' => Ok(TFormBinaryTableType::E(TFormBinaryTable::new(count))), // Single-precision floating point + 'D' => Ok(TFormBinaryTableType::D(TFormBinaryTable::new(count))), // Double-precision floating point + 'C' => Ok(TFormBinaryTableType::C(TFormBinaryTable::new(count))), // Single-precision complex + 'M' => Ok(TFormBinaryTableType::M(TFormBinaryTable::new(count))), // Double-precision complex + 'P' => Ok(TFormBinaryTableType::P(TFormBinaryTable::new(count))), // Array Descriptor (32-bit) + 'Q' => Ok(TFormBinaryTableType::Q(TFormBinaryTable::new(count))), // Array Descriptor (64-bit) _ => Err(Error::StaticError("Ascii Table TFORM not recognized")), } }) diff --git a/src/lib.rs b/src/lib.rs index f2af1fb..23e216c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,6 @@ extern crate async_trait; extern crate byteorder; -extern crate nom; #[macro_use] extern crate quick_error;