flow_fcs/datatype.rs
1use anyhow::{Result, anyhow};
2use serde::{Deserialize, Serialize};
3use strum_macros::Display;
4
5/// The data type of the FCS file, which determines how event data is stored
6///
7/// FCS files can store data in different numeric formats. The most common is
8/// single-precision floating point (F), which is also the default.
9#[derive(Default, Display, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
10pub enum FcsDataType {
11 /// Unsigned binary integer
12 I,
13 /// Single-precision floating point (f32)
14 #[default]
15 F,
16 /// Double-precision floating point (f64)
17 D,
18 /// ASCII-encoded string (not supported)
19 A,
20}
21impl FcsDataType {
22 /// Matches the string pattern and returns the corresponding data type
23 /// # Errors
24 /// Will return `Err` if `data_type` is not a valid data type (ASCII-encoded strings are not supported, but binary integers, single-precision floating point, and double-precision floating point are supported)
25 pub fn from_keyword_str(data_type: &str) -> Result<Self> {
26 match data_type {
27 "I" => Ok(Self::I),
28 "F" => Ok(Self::F),
29 "D" => Ok(Self::D),
30 "A" => Err(anyhow!("ASCII-encoded string data type not supported")),
31 _ => Err(anyhow!("Invalid data type")),
32 }
33 }
34
35 /// Returns the keyword string representation of the data type
36 pub fn to_keyword_str(&self) -> &str {
37 match self {
38 Self::I => "I (unsigned binary integer)",
39 Self::F => "F (single-precision floating point)",
40 Self::D => "D (double-precision floating point)",
41 Self::A => "A (ASCII-encoded string)",
42 }
43 }
44
45 /// Returns the number of bytes for the data type based on the number of bits
46 ///
47 /// This is used in conjunction with `$PnB` to determine the actual bytes per parameter.
48 /// For `I` (integer) type, the actual bytes depend on `$PnB` (e.g., 16 bits = 2 bytes, 32 bits = 4 bytes).
49 /// For `F` (float32), always 4 bytes.
50 /// For `D` (float64), always 8 bytes.
51 ///
52 /// # Arguments
53 /// * `bits` - Number of bits from `$PnB` keyword
54 ///
55 /// # Returns
56 /// Number of bytes for this data type with the given bit width
57 #[must_use]
58 pub fn get_bytes_for_bits(&self, bits: usize) -> usize {
59 match self {
60 Self::I => (bits + 7) / 8, // Convert bits to bytes, rounding up
61 Self::F => 4,
62 Self::D => 8,
63 Self::A => 0,
64 }
65 }
66}