Skip to main content

zarrs/array/data_type/
subfloat.rs

1//! Subfloat data types (sub-byte floating point formats).
2
3use super::macros::register_data_type_plugin;
4
5/// Macro to implement `DataTypeTraits` for subfloat types (single-byte floating point formats).
6macro_rules! impl_subfloat_data_type {
7    ($marker:ty) => {
8        impl zarrs_data_type::DataTypeTraits for $marker {
9            fn configuration(
10                &self,
11                _version: zarrs_plugin::ZarrVersion,
12            ) -> zarrs_metadata::Configuration {
13                zarrs_metadata::Configuration::default()
14            }
15
16            fn size(&self) -> zarrs_metadata::DataTypeSize {
17                zarrs_metadata::DataTypeSize::Fixed(1)
18            }
19
20            fn fill_value(
21                &self,
22                fill_value_metadata: &zarrs_metadata::FillValueMetadata,
23                _version: zarrs_plugin::ZarrVersion,
24            ) -> Result<zarrs_data_type::FillValue, zarrs_data_type::DataTypeFillValueMetadataError>
25            {
26                // Subfloats use hex string representation like "0x00"
27                if let Some(s) = fill_value_metadata.as_str() {
28                    if let Some(hex) = s.strip_prefix("0x") {
29                        if let Ok(byte) = u8::from_str_radix(hex, 16) {
30                            return Ok(zarrs_data_type::FillValue::from(byte));
31                        }
32                    }
33                }
34                // Also accept integer values in range
35                if let Some(int) = fill_value_metadata.as_u64() {
36                    if let Ok(byte) = u8::try_from(int) {
37                        return Ok(zarrs_data_type::FillValue::from(byte));
38                    }
39                }
40                Err(zarrs_data_type::DataTypeFillValueMetadataError)
41            }
42
43            fn metadata_fill_value(
44                &self,
45                fill_value: &zarrs_data_type::FillValue,
46            ) -> Result<zarrs_metadata::FillValueMetadata, zarrs_data_type::DataTypeFillValueError>
47            {
48                let bytes: [u8; 1] = fill_value
49                    .as_ne_bytes()
50                    .try_into()
51                    .map_err(|_| zarrs_data_type::DataTypeFillValueError)?;
52                // Return as hex string
53                Ok(zarrs_metadata::FillValueMetadata::from(format!(
54                    "0x{:02x}",
55                    bytes[0]
56                )))
57            }
58
59            fn as_any(&self) -> &dyn std::any::Any {
60                self
61            }
62        }
63    };
64}
65
66/// The `float4_e2m1fn` data type.
67#[derive(Debug, Clone, Copy)]
68pub struct Float4E2M1FNDataType;
69register_data_type_plugin!(Float4E2M1FNDataType);
70zarrs_plugin::impl_extension_aliases!(Float4E2M1FNDataType, v3: "float4_e2m1fn");
71
72/// The `float6_e2m3fn` data type.
73#[derive(Debug, Clone, Copy)]
74pub struct Float6E2M3FNDataType;
75register_data_type_plugin!(Float6E2M3FNDataType);
76zarrs_plugin::impl_extension_aliases!(Float6E2M3FNDataType, v3: "float6_e2m3fn");
77
78/// The `float6_e3m2fn` data type.
79#[derive(Debug, Clone, Copy)]
80pub struct Float6E3M2FNDataType;
81register_data_type_plugin!(Float6E3M2FNDataType);
82zarrs_plugin::impl_extension_aliases!(Float6E3M2FNDataType, v3: "float6_e3m2fn");
83
84/// The `float8_e3m4` data type.
85#[derive(Debug, Clone, Copy)]
86pub struct Float8E3M4DataType;
87register_data_type_plugin!(Float8E3M4DataType);
88zarrs_plugin::impl_extension_aliases!(Float8E3M4DataType, v3: "float8_e3m4");
89
90/// The `float8_e4m3b11fnuz` data type.
91#[derive(Debug, Clone, Copy)]
92pub struct Float8E4M3B11FNUZDataType;
93register_data_type_plugin!(Float8E4M3B11FNUZDataType);
94zarrs_plugin::impl_extension_aliases!(Float8E4M3B11FNUZDataType, v3: "float8_e4m3b11fnuz");
95
96/// The `float8_e4m3fnuz` data type.
97#[derive(Debug, Clone, Copy)]
98pub struct Float8E4M3FNUZDataType;
99register_data_type_plugin!(Float8E4M3FNUZDataType);
100zarrs_plugin::impl_extension_aliases!(Float8E4M3FNUZDataType, v3: "float8_e4m3fnuz");
101
102/// The `float8_e5m2fnuz` data type.
103#[derive(Debug, Clone, Copy)]
104pub struct Float8E5M2FNUZDataType;
105register_data_type_plugin!(Float8E5M2FNUZDataType);
106zarrs_plugin::impl_extension_aliases!(Float8E5M2FNUZDataType, v3: "float8_e5m2fnuz");
107
108/// The `float8_e8m0fnu` data type.
109#[derive(Debug, Clone, Copy)]
110pub struct Float8E8M0FNUDataType;
111register_data_type_plugin!(Float8E8M0FNUDataType);
112zarrs_plugin::impl_extension_aliases!(Float8E8M0FNUDataType, v3: "float8_e8m0fnu");
113
114// DataTypeTraits implementations for subfloats
115impl_subfloat_data_type!(Float4E2M1FNDataType);
116impl_subfloat_data_type!(Float6E2M3FNDataType);
117impl_subfloat_data_type!(Float6E3M2FNDataType);
118impl_subfloat_data_type!(Float8E3M4DataType);
119impl_subfloat_data_type!(Float8E4M3B11FNUZDataType);
120impl_subfloat_data_type!(Float8E4M3FNUZDataType);
121impl_subfloat_data_type!(Float8E5M2FNUZDataType);
122impl_subfloat_data_type!(Float8E8M0FNUDataType);
123
124// PackBits codec implementations for subfloats
125use zarrs_data_type::codec_traits::impl_pack_bits_data_type_traits;
126impl_pack_bits_data_type_traits!(Float4E2M1FNDataType, 4, float, 1);
127impl_pack_bits_data_type_traits!(Float6E2M3FNDataType, 6, float, 1);
128impl_pack_bits_data_type_traits!(Float6E3M2FNDataType, 6, float, 1);
129impl_pack_bits_data_type_traits!(Float8E3M4DataType, 8, float, 1);
130impl_pack_bits_data_type_traits!(Float8E4M3B11FNUZDataType, 8, float, 1);
131impl_pack_bits_data_type_traits!(Float8E4M3FNUZDataType, 8, float, 1);
132impl_pack_bits_data_type_traits!(Float8E5M2FNUZDataType, 8, float, 1);
133impl_pack_bits_data_type_traits!(Float8E8M0FNUDataType, 8, float, 1);
134
135// Bytes codec implementations for subfloats (passthrough - single byte, no endianness conversion)
136use zarrs_data_type::codec_traits::impl_bytes_data_type_traits;
137impl_bytes_data_type_traits!(Float4E2M1FNDataType, 1);
138impl_bytes_data_type_traits!(Float6E2M3FNDataType, 1);
139impl_bytes_data_type_traits!(Float6E3M2FNDataType, 1);
140impl_bytes_data_type_traits!(Float8E3M4DataType, 1);
141impl_bytes_data_type_traits!(Float8E4M3B11FNUZDataType, 1);
142impl_bytes_data_type_traits!(Float8E4M3FNUZDataType, 1);
143impl_bytes_data_type_traits!(Float8E5M2FNUZDataType, 1);
144impl_bytes_data_type_traits!(Float8E8M0FNUDataType, 1);