Skip to main content

ArrayBuilder

Struct ArrayBuilder 

Source
pub struct ArrayBuilder { /* private fields */ }
Expand description

An Array builder.

ArrayBuilder is initialised from an array shape, data type, chunk grid, and fill value.

  • The default array-to-bytes codec is dependent on the data type:
  • Array-to-array and bytes-to-bytes codecs are empty by default.
  • The default chunk key encoding is default with the / chunk key separator.
  • Attributes, storage transformers, and dimension names are empty.

Use the methods in the array builder to change the configuration away from these defaults, and then build the array at a path of some storage with ArrayBuilder::build.

build does not modify the store! Array metadata has to be explicitly written with Array::store_metadata.

§Simple Example

This array is uncompressed, and has no dimension names or attributes.

use zarrs::array::{ArrayBuilder, DataType, FillValue, ZARR_NAN_F32, data_type};
let mut array = ArrayBuilder::new(
    vec![8, 8], // array shape
    vec![4, 4], // regular chunk shape
    data_type::float32(), // data type
    f32::NAN, // fill value
)
.build(store.clone(), "/group/array")?;
array.store_metadata()?; // write metadata to the store

§Advanced Example

The array is compressed with the zstd codec, dimension names are set, and the experimental rectangular chunk grid is used.

This example uses alternative types to specify the array shape, data type, chunk grid, and fill value. In general you don’t want to use strings, prefer concrete types (like RectangularChunkGridConfiguration, for example).

use zarrs::array::{ArrayBuilder, DataType, FillValue, ZARR_NAN_F32};
let mut array = ArrayBuilder::new(
    [8, 8],
    r#"{"name":"rectangular","configuration":{"chunk_shape": [[1, 2, 5], 4]}}"#,
    "float32",
    "NaN",
)
.bytes_to_bytes_codecs(vec![
    #[cfg(feature = "zstd")]
    Arc::new(zarrs::array::codec::ZstdCodec::new(5, false)),
])
.dimension_names(Some(["y", "x"]))
.build(store.clone(), "/group/array")?;
array.store_metadata()?; // write metadata to the store

Implementations§

Source§

impl ArrayBuilder

Source

pub fn new( shape: impl Into<ArrayShape>, chunk_grid_metadata: impl Into<ArrayBuilderChunkGridMetadata>, data_type: impl Into<ArrayBuilderDataType>, fill_value: impl Into<ArrayBuilderFillValue>, ) -> Self

Create a new array builder for an array at path from an array shape and chunk grid metadata.

The length of the array shape must match the dimensionality of the intended array. Some chunk grids (e.g. regular) support all zero shape, indicating the shape is unbounded.

Examples found in repository?
examples/custom_data_type_variable_size.rs (lines 160-165)
157fn main() {
158    let store = std::sync::Arc::new(MemoryStore::default());
159    let array_path = "/array";
160    let array = ArrayBuilder::new(
161        vec![4, 1], // array shape
162        vec![3, 1], // regular chunk shape
163        Arc::new(CustomDataTypeVariableSize),
164        [],
165    )
166    .array_to_array_codecs(vec![
167        #[cfg(feature = "transpose")]
168        Arc::new(zarrs::array::codec::TransposeCodec::new(
169            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170        )),
171    ])
172    .bytes_to_bytes_codecs(vec![
173        #[cfg(feature = "gzip")]
174        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175        #[cfg(feature = "crc32c")]
176        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177    ])
178    // .storage_transformers(vec![].into())
179    .build(store, array_path)
180    .unwrap();
181    println!("{}", array.metadata().to_string_pretty());
182
183    let data = [
184        CustomDataTypeVariableSizeElement::from(Some(1.0)),
185        CustomDataTypeVariableSizeElement::from(None),
186        CustomDataTypeVariableSizeElement::from(Some(3.0)),
187    ];
188    array.store_chunk(&[0, 0], &data).unwrap();
189
190    let data: Vec<CustomDataTypeVariableSizeElement> =
191        array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193    assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194    assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195    assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196    assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198    println!("{data:#?}");
199}
More examples
Hide additional examples
examples/custom_data_type_fixed_size.rs (lines 284-289)
280fn main() {
281    let store = std::sync::Arc::new(MemoryStore::default());
282    let array_path = "/array";
283    let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284    let array = ArrayBuilder::new(
285        vec![4, 1], // array shape
286        vec![2, 1], // regular chunk shape
287        Arc::new(CustomDataTypeFixedSize),
288        FillValue::new(fill_value.to_ne_bytes().to_vec()),
289    )
290    .array_to_array_codecs(vec![
291        #[cfg(feature = "transpose")]
292        Arc::new(zarrs::array::codec::TransposeCodec::new(
293            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294        )),
295    ])
296    .bytes_to_bytes_codecs(vec![
297        #[cfg(feature = "gzip")]
298        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299        #[cfg(feature = "crc32c")]
300        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301    ])
302    // .storage_transformers(vec![].into())
303    .build(store, array_path)
304    .unwrap();
305    println!("{}", array.metadata().to_string_pretty());
306
307    let data = [
308        CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309        CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310    ];
311    array.store_chunk(&[0, 0], &data).unwrap();
312
313    let data: Vec<CustomDataTypeFixedSizeElement> =
314        array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316    assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317    assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318    assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319    assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321    println!("{data:#?}");
322}
examples/custom_data_type_uint12.rs (lines 196-201)
192fn main() {
193    let store = std::sync::Arc::new(MemoryStore::default());
194    let array_path = "/array";
195    let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196    let array = ArrayBuilder::new(
197        vec![4096, 1], // array shape
198        vec![5, 1],    // regular chunk shape
199        Arc::new(CustomDataTypeUInt12),
200        FillValue::new(fill_value.into_le_bytes().to_vec()),
201    )
202    .array_to_array_codecs(vec![
203        #[cfg(feature = "transpose")]
204        Arc::new(zarrs::array::codec::TransposeCodec::new(
205            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206        )),
207    ])
208    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209    .bytes_to_bytes_codecs(vec![
210        #[cfg(feature = "gzip")]
211        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212        #[cfg(feature = "crc32c")]
213        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214    ])
215    // .storage_transformers(vec![].into())
216    .build(store, array_path)
217    .unwrap();
218    println!("{}", array.metadata().to_string_pretty());
219
220    let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221        .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222        .collect();
223
224    array
225        .store_array_subset(&array.subset_all(), &data)
226        .unwrap();
227
228    let mut data: Vec<CustomDataTypeUInt12Element> =
229        array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231    for (i, d) in data.drain(0..4096).enumerate() {
232        let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233        assert_eq!(d, element);
234        let element_pd: Vec<CustomDataTypeUInt12Element> = array
235            .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236            .unwrap();
237        assert_eq!(element_pd[0], element);
238    }
239}
examples/custom_data_type_float8_e3m4.rs (lines 207-212)
203fn main() {
204    let store = std::sync::Arc::new(MemoryStore::default());
205    let array_path = "/array";
206    let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207    let array = ArrayBuilder::new(
208        vec![6, 1], // array shape
209        vec![5, 1], // regular chunk shape
210        Arc::new(CustomDataTypeFloat8e3m4),
211        FillValue::new(fill_value.into_ne_bytes().to_vec()),
212    )
213    .array_to_array_codecs(vec![
214        #[cfg(feature = "transpose")]
215        Arc::new(zarrs::array::codec::TransposeCodec::new(
216            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217        )),
218    ])
219    .bytes_to_bytes_codecs(vec![
220        #[cfg(feature = "gzip")]
221        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222        #[cfg(feature = "crc32c")]
223        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224    ])
225    // .storage_transformers(vec![].into())
226    .build(store, array_path)
227    .unwrap();
228    println!("{}", array.metadata().to_string_pretty());
229
230    let data = [
231        CustomDataTypeFloat8e3m4Element::from(2.34),
232        CustomDataTypeFloat8e3m4Element::from(3.45),
233        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235        CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236    ];
237    array.store_chunk(&[0, 0], &data).unwrap();
238
239    let data: Vec<CustomDataTypeFloat8e3m4Element> =
240        array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242    for f in &data {
243        println!(
244            "float8_e3m4: {:08b} f32: {}",
245            f.into_ne_bytes()[0],
246            f.into_f32()
247        );
248    }
249
250    assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251    assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252    assert_eq!(
253        data[2],
254        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255    );
256    assert_eq!(
257        data[3],
258        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259    );
260    assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261    assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}
examples/custom_data_type_uint4.rs (lines 198-203)
194fn main() {
195    let store = std::sync::Arc::new(MemoryStore::default());
196    let array_path = "/array";
197    let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198    let array = ArrayBuilder::new(
199        vec![6, 1], // array shape
200        vec![5, 1], // regular chunk shape
201        Arc::new(CustomDataTypeUInt4),
202        FillValue::new(fill_value.into_ne_bytes().to_vec()),
203    )
204    .array_to_array_codecs(vec![
205        #[cfg(feature = "transpose")]
206        Arc::new(zarrs::array::codec::TransposeCodec::new(
207            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208        )),
209    ])
210    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211    .bytes_to_bytes_codecs(vec![
212        #[cfg(feature = "gzip")]
213        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214        #[cfg(feature = "crc32c")]
215        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216    ])
217    // .storage_transformers(vec![].into())
218    .build(store, array_path)
219    .unwrap();
220    println!("{}", array.metadata().to_string_pretty());
221
222    let data = [
223        CustomDataTypeUInt4Element::try_from(1).unwrap(),
224        CustomDataTypeUInt4Element::try_from(2).unwrap(),
225        CustomDataTypeUInt4Element::try_from(3).unwrap(),
226        CustomDataTypeUInt4Element::try_from(4).unwrap(),
227        CustomDataTypeUInt4Element::try_from(5).unwrap(),
228    ];
229    array.store_chunk(&[0, 0], &data).unwrap();
230
231    let data: Vec<CustomDataTypeUInt4Element> =
232        array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234    for f in &data {
235        println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236    }
237
238    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240    assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241    assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242    assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243    assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245    let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}
examples/data_type_optional_nested.rs (lines 19-24)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12    // Create an in-memory store
13    // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14    //     "zarrs/tests/data/v3/array_optional_nested.zarr",
15    // )?);
16    let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18    // Build the codec chains for the optional codec
19    let array = ArrayBuilder::new(
20        vec![4, 4],                                     // 4x4 array
21        vec![2, 2],                                     // 2x2 chunks
22        data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23        FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24    )
25    .dimension_names(["y", "x"].into())
26    .attributes(
27        serde_json::json!({
28            "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31  N  SN   2   3 
32  N   5   N   7 
33 SN  SN   N   N 
34 SN  SN   N   N"#,
35        })
36        .as_object()
37        .unwrap()
38        .clone(),
39    )
40    .build(store.clone(), "/array")?;
41    array.store_metadata_opt(
42        &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43    )?;
44
45    println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47    // Create some data with missing values
48    let data = ndarray::array![
49        [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50        [None, Some(Some(5u8)), None, Some(Some(7u8))],
51        [Some(None), Some(None), None, None],
52        [Some(None), Some(None), None, None],
53    ]
54    .into_dyn();
55
56    // Write the data
57    array.store_array_subset(&array.subset_all(), data.clone())?;
58    println!("Data written to array.");
59
60    // Read back the data
61    let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63    // Verify data integrity
64    assert_eq!(data, data_read);
65
66    // Display the data in a grid format
67    println!(
68        "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69    );
70    println!("    0   1   2   3");
71    for y in 0..4 {
72        print!("{} ", y);
73        for x in 0..4 {
74            match data_read[[y, x]] {
75                Some(Some(value)) => print!("{:3} ", value),
76                Some(None) => print!(" SN "),
77                None => print!("  N "),
78            }
79        }
80        println!();
81    }
82    Ok(())
83}
Source

pub fn new_with_chunk_grid( chunk_grid: impl Into<ChunkGrid>, data_type: impl Into<ArrayBuilderDataType>, fill_value: impl Into<ArrayBuilderFillValue>, ) -> Self

Create a new array builder with a concrete chunk grid (with an associated array shape).

Source

pub fn from_array<T: ?Sized>(array: &Array<T>) -> Self

Create a new builder copying the configuration of an existing array.

Source

pub fn shape(&mut self, shape: impl Into<ArrayShape>) -> &mut Self

Set the shape.

Source

pub fn data_type( &mut self, data_type: impl Into<ArrayBuilderDataType>, ) -> &mut Self

Set the data type.

Source

pub fn chunk_grid_metadata( &mut self, chunk_grid_metadata: impl Into<ArrayBuilderChunkGridMetadata>, ) -> &mut Self

Set the chunk grid metadata.

Source

pub fn chunk_grid(&mut self, chunk_grid: impl Into<ChunkGrid>) -> &mut Self

Set the chunk grid. This may also change the array shape.

Source

pub fn fill_value( &mut self, fill_value: impl Into<ArrayBuilderFillValue>, ) -> &mut Self

Set the fill value.

Source

pub fn chunk_key_encoding( &mut self, chunk_key_encoding: impl Into<ChunkKeyEncoding>, ) -> &mut Self

Set the chunk key encoding.

If left unmodified, the array will use default chunk key encoding with the / chunk key separator.

Source

pub fn chunk_key_encoding_default_separator( &mut self, separator: ChunkKeySeparator, ) -> &mut Self

Set the chunk key encoding to default with separator.

If left unmodified, the array will use default chunk key encoding with the / chunk key separator.

Source

pub fn array_to_array_codecs( &mut self, array_to_array_codecs: Vec<Arc<dyn ArrayToArrayCodecTraits>>, ) -> &mut Self

Set the array-to-array codecs.

If left unmodified, the array will have no array-to-array codecs.

Examples found in repository?
examples/custom_data_type_variable_size.rs (lines 166-171)
157fn main() {
158    let store = std::sync::Arc::new(MemoryStore::default());
159    let array_path = "/array";
160    let array = ArrayBuilder::new(
161        vec![4, 1], // array shape
162        vec![3, 1], // regular chunk shape
163        Arc::new(CustomDataTypeVariableSize),
164        [],
165    )
166    .array_to_array_codecs(vec![
167        #[cfg(feature = "transpose")]
168        Arc::new(zarrs::array::codec::TransposeCodec::new(
169            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170        )),
171    ])
172    .bytes_to_bytes_codecs(vec![
173        #[cfg(feature = "gzip")]
174        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175        #[cfg(feature = "crc32c")]
176        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177    ])
178    // .storage_transformers(vec![].into())
179    .build(store, array_path)
180    .unwrap();
181    println!("{}", array.metadata().to_string_pretty());
182
183    let data = [
184        CustomDataTypeVariableSizeElement::from(Some(1.0)),
185        CustomDataTypeVariableSizeElement::from(None),
186        CustomDataTypeVariableSizeElement::from(Some(3.0)),
187    ];
188    array.store_chunk(&[0, 0], &data).unwrap();
189
190    let data: Vec<CustomDataTypeVariableSizeElement> =
191        array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193    assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194    assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195    assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196    assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198    println!("{data:#?}");
199}
More examples
Hide additional examples
examples/custom_data_type_fixed_size.rs (lines 290-295)
280fn main() {
281    let store = std::sync::Arc::new(MemoryStore::default());
282    let array_path = "/array";
283    let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284    let array = ArrayBuilder::new(
285        vec![4, 1], // array shape
286        vec![2, 1], // regular chunk shape
287        Arc::new(CustomDataTypeFixedSize),
288        FillValue::new(fill_value.to_ne_bytes().to_vec()),
289    )
290    .array_to_array_codecs(vec![
291        #[cfg(feature = "transpose")]
292        Arc::new(zarrs::array::codec::TransposeCodec::new(
293            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294        )),
295    ])
296    .bytes_to_bytes_codecs(vec![
297        #[cfg(feature = "gzip")]
298        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299        #[cfg(feature = "crc32c")]
300        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301    ])
302    // .storage_transformers(vec![].into())
303    .build(store, array_path)
304    .unwrap();
305    println!("{}", array.metadata().to_string_pretty());
306
307    let data = [
308        CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309        CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310    ];
311    array.store_chunk(&[0, 0], &data).unwrap();
312
313    let data: Vec<CustomDataTypeFixedSizeElement> =
314        array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316    assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317    assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318    assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319    assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321    println!("{data:#?}");
322}
examples/custom_data_type_uint12.rs (lines 202-207)
192fn main() {
193    let store = std::sync::Arc::new(MemoryStore::default());
194    let array_path = "/array";
195    let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196    let array = ArrayBuilder::new(
197        vec![4096, 1], // array shape
198        vec![5, 1],    // regular chunk shape
199        Arc::new(CustomDataTypeUInt12),
200        FillValue::new(fill_value.into_le_bytes().to_vec()),
201    )
202    .array_to_array_codecs(vec![
203        #[cfg(feature = "transpose")]
204        Arc::new(zarrs::array::codec::TransposeCodec::new(
205            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206        )),
207    ])
208    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209    .bytes_to_bytes_codecs(vec![
210        #[cfg(feature = "gzip")]
211        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212        #[cfg(feature = "crc32c")]
213        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214    ])
215    // .storage_transformers(vec![].into())
216    .build(store, array_path)
217    .unwrap();
218    println!("{}", array.metadata().to_string_pretty());
219
220    let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221        .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222        .collect();
223
224    array
225        .store_array_subset(&array.subset_all(), &data)
226        .unwrap();
227
228    let mut data: Vec<CustomDataTypeUInt12Element> =
229        array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231    for (i, d) in data.drain(0..4096).enumerate() {
232        let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233        assert_eq!(d, element);
234        let element_pd: Vec<CustomDataTypeUInt12Element> = array
235            .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236            .unwrap();
237        assert_eq!(element_pd[0], element);
238    }
239}
examples/custom_data_type_float8_e3m4.rs (lines 213-218)
203fn main() {
204    let store = std::sync::Arc::new(MemoryStore::default());
205    let array_path = "/array";
206    let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207    let array = ArrayBuilder::new(
208        vec![6, 1], // array shape
209        vec![5, 1], // regular chunk shape
210        Arc::new(CustomDataTypeFloat8e3m4),
211        FillValue::new(fill_value.into_ne_bytes().to_vec()),
212    )
213    .array_to_array_codecs(vec![
214        #[cfg(feature = "transpose")]
215        Arc::new(zarrs::array::codec::TransposeCodec::new(
216            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217        )),
218    ])
219    .bytes_to_bytes_codecs(vec![
220        #[cfg(feature = "gzip")]
221        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222        #[cfg(feature = "crc32c")]
223        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224    ])
225    // .storage_transformers(vec![].into())
226    .build(store, array_path)
227    .unwrap();
228    println!("{}", array.metadata().to_string_pretty());
229
230    let data = [
231        CustomDataTypeFloat8e3m4Element::from(2.34),
232        CustomDataTypeFloat8e3m4Element::from(3.45),
233        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235        CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236    ];
237    array.store_chunk(&[0, 0], &data).unwrap();
238
239    let data: Vec<CustomDataTypeFloat8e3m4Element> =
240        array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242    for f in &data {
243        println!(
244            "float8_e3m4: {:08b} f32: {}",
245            f.into_ne_bytes()[0],
246            f.into_f32()
247        );
248    }
249
250    assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251    assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252    assert_eq!(
253        data[2],
254        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255    );
256    assert_eq!(
257        data[3],
258        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259    );
260    assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261    assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}
examples/custom_data_type_uint4.rs (lines 204-209)
194fn main() {
195    let store = std::sync::Arc::new(MemoryStore::default());
196    let array_path = "/array";
197    let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198    let array = ArrayBuilder::new(
199        vec![6, 1], // array shape
200        vec![5, 1], // regular chunk shape
201        Arc::new(CustomDataTypeUInt4),
202        FillValue::new(fill_value.into_ne_bytes().to_vec()),
203    )
204    .array_to_array_codecs(vec![
205        #[cfg(feature = "transpose")]
206        Arc::new(zarrs::array::codec::TransposeCodec::new(
207            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208        )),
209    ])
210    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211    .bytes_to_bytes_codecs(vec![
212        #[cfg(feature = "gzip")]
213        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214        #[cfg(feature = "crc32c")]
215        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216    ])
217    // .storage_transformers(vec![].into())
218    .build(store, array_path)
219    .unwrap();
220    println!("{}", array.metadata().to_string_pretty());
221
222    let data = [
223        CustomDataTypeUInt4Element::try_from(1).unwrap(),
224        CustomDataTypeUInt4Element::try_from(2).unwrap(),
225        CustomDataTypeUInt4Element::try_from(3).unwrap(),
226        CustomDataTypeUInt4Element::try_from(4).unwrap(),
227        CustomDataTypeUInt4Element::try_from(5).unwrap(),
228    ];
229    array.store_chunk(&[0, 0], &data).unwrap();
230
231    let data: Vec<CustomDataTypeUInt4Element> =
232        array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234    for f in &data {
235        println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236    }
237
238    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240    assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241    assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242    assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243    assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245    let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}
Source

pub fn array_to_bytes_codec( &mut self, array_to_bytes_codec: Arc<dyn ArrayToBytesCodecTraits>, ) -> &mut Self

Set the array-to-bytes codec.

If left unmodified, the array will default to using the bytes codec with native endian encoding.

Examples found in repository?
examples/custom_data_type_uint12.rs (line 208)
192fn main() {
193    let store = std::sync::Arc::new(MemoryStore::default());
194    let array_path = "/array";
195    let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196    let array = ArrayBuilder::new(
197        vec![4096, 1], // array shape
198        vec![5, 1],    // regular chunk shape
199        Arc::new(CustomDataTypeUInt12),
200        FillValue::new(fill_value.into_le_bytes().to_vec()),
201    )
202    .array_to_array_codecs(vec![
203        #[cfg(feature = "transpose")]
204        Arc::new(zarrs::array::codec::TransposeCodec::new(
205            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206        )),
207    ])
208    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209    .bytes_to_bytes_codecs(vec![
210        #[cfg(feature = "gzip")]
211        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212        #[cfg(feature = "crc32c")]
213        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214    ])
215    // .storage_transformers(vec![].into())
216    .build(store, array_path)
217    .unwrap();
218    println!("{}", array.metadata().to_string_pretty());
219
220    let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221        .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222        .collect();
223
224    array
225        .store_array_subset(&array.subset_all(), &data)
226        .unwrap();
227
228    let mut data: Vec<CustomDataTypeUInt12Element> =
229        array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231    for (i, d) in data.drain(0..4096).enumerate() {
232        let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233        assert_eq!(d, element);
234        let element_pd: Vec<CustomDataTypeUInt12Element> = array
235            .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236            .unwrap();
237        assert_eq!(element_pd[0], element);
238    }
239}
More examples
Hide additional examples
examples/custom_data_type_uint4.rs (line 210)
194fn main() {
195    let store = std::sync::Arc::new(MemoryStore::default());
196    let array_path = "/array";
197    let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198    let array = ArrayBuilder::new(
199        vec![6, 1], // array shape
200        vec![5, 1], // regular chunk shape
201        Arc::new(CustomDataTypeUInt4),
202        FillValue::new(fill_value.into_ne_bytes().to_vec()),
203    )
204    .array_to_array_codecs(vec![
205        #[cfg(feature = "transpose")]
206        Arc::new(zarrs::array::codec::TransposeCodec::new(
207            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208        )),
209    ])
210    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211    .bytes_to_bytes_codecs(vec![
212        #[cfg(feature = "gzip")]
213        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214        #[cfg(feature = "crc32c")]
215        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216    ])
217    // .storage_transformers(vec![].into())
218    .build(store, array_path)
219    .unwrap();
220    println!("{}", array.metadata().to_string_pretty());
221
222    let data = [
223        CustomDataTypeUInt4Element::try_from(1).unwrap(),
224        CustomDataTypeUInt4Element::try_from(2).unwrap(),
225        CustomDataTypeUInt4Element::try_from(3).unwrap(),
226        CustomDataTypeUInt4Element::try_from(4).unwrap(),
227        CustomDataTypeUInt4Element::try_from(5).unwrap(),
228    ];
229    array.store_chunk(&[0, 0], &data).unwrap();
230
231    let data: Vec<CustomDataTypeUInt4Element> =
232        array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234    for f in &data {
235        println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236    }
237
238    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240    assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241    assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242    assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243    assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245    let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}
Source

pub fn bytes_to_bytes_codecs( &mut self, bytes_to_bytes_codecs: Vec<Arc<dyn BytesToBytesCodecTraits>>, ) -> &mut Self

Set the bytes-to-bytes codecs.

If left unmodified, the array will have no bytes-to-bytes codecs.

Examples found in repository?
examples/custom_data_type_variable_size.rs (lines 172-177)
157fn main() {
158    let store = std::sync::Arc::new(MemoryStore::default());
159    let array_path = "/array";
160    let array = ArrayBuilder::new(
161        vec![4, 1], // array shape
162        vec![3, 1], // regular chunk shape
163        Arc::new(CustomDataTypeVariableSize),
164        [],
165    )
166    .array_to_array_codecs(vec![
167        #[cfg(feature = "transpose")]
168        Arc::new(zarrs::array::codec::TransposeCodec::new(
169            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170        )),
171    ])
172    .bytes_to_bytes_codecs(vec![
173        #[cfg(feature = "gzip")]
174        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175        #[cfg(feature = "crc32c")]
176        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177    ])
178    // .storage_transformers(vec![].into())
179    .build(store, array_path)
180    .unwrap();
181    println!("{}", array.metadata().to_string_pretty());
182
183    let data = [
184        CustomDataTypeVariableSizeElement::from(Some(1.0)),
185        CustomDataTypeVariableSizeElement::from(None),
186        CustomDataTypeVariableSizeElement::from(Some(3.0)),
187    ];
188    array.store_chunk(&[0, 0], &data).unwrap();
189
190    let data: Vec<CustomDataTypeVariableSizeElement> =
191        array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193    assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194    assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195    assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196    assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198    println!("{data:#?}");
199}
More examples
Hide additional examples
examples/custom_data_type_fixed_size.rs (lines 296-301)
280fn main() {
281    let store = std::sync::Arc::new(MemoryStore::default());
282    let array_path = "/array";
283    let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284    let array = ArrayBuilder::new(
285        vec![4, 1], // array shape
286        vec![2, 1], // regular chunk shape
287        Arc::new(CustomDataTypeFixedSize),
288        FillValue::new(fill_value.to_ne_bytes().to_vec()),
289    )
290    .array_to_array_codecs(vec![
291        #[cfg(feature = "transpose")]
292        Arc::new(zarrs::array::codec::TransposeCodec::new(
293            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294        )),
295    ])
296    .bytes_to_bytes_codecs(vec![
297        #[cfg(feature = "gzip")]
298        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299        #[cfg(feature = "crc32c")]
300        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301    ])
302    // .storage_transformers(vec![].into())
303    .build(store, array_path)
304    .unwrap();
305    println!("{}", array.metadata().to_string_pretty());
306
307    let data = [
308        CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309        CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310    ];
311    array.store_chunk(&[0, 0], &data).unwrap();
312
313    let data: Vec<CustomDataTypeFixedSizeElement> =
314        array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316    assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317    assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318    assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319    assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321    println!("{data:#?}");
322}
examples/custom_data_type_uint12.rs (lines 209-214)
192fn main() {
193    let store = std::sync::Arc::new(MemoryStore::default());
194    let array_path = "/array";
195    let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196    let array = ArrayBuilder::new(
197        vec![4096, 1], // array shape
198        vec![5, 1],    // regular chunk shape
199        Arc::new(CustomDataTypeUInt12),
200        FillValue::new(fill_value.into_le_bytes().to_vec()),
201    )
202    .array_to_array_codecs(vec![
203        #[cfg(feature = "transpose")]
204        Arc::new(zarrs::array::codec::TransposeCodec::new(
205            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206        )),
207    ])
208    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209    .bytes_to_bytes_codecs(vec![
210        #[cfg(feature = "gzip")]
211        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212        #[cfg(feature = "crc32c")]
213        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214    ])
215    // .storage_transformers(vec![].into())
216    .build(store, array_path)
217    .unwrap();
218    println!("{}", array.metadata().to_string_pretty());
219
220    let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221        .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222        .collect();
223
224    array
225        .store_array_subset(&array.subset_all(), &data)
226        .unwrap();
227
228    let mut data: Vec<CustomDataTypeUInt12Element> =
229        array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231    for (i, d) in data.drain(0..4096).enumerate() {
232        let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233        assert_eq!(d, element);
234        let element_pd: Vec<CustomDataTypeUInt12Element> = array
235            .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236            .unwrap();
237        assert_eq!(element_pd[0], element);
238    }
239}
examples/custom_data_type_float8_e3m4.rs (lines 219-224)
203fn main() {
204    let store = std::sync::Arc::new(MemoryStore::default());
205    let array_path = "/array";
206    let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207    let array = ArrayBuilder::new(
208        vec![6, 1], // array shape
209        vec![5, 1], // regular chunk shape
210        Arc::new(CustomDataTypeFloat8e3m4),
211        FillValue::new(fill_value.into_ne_bytes().to_vec()),
212    )
213    .array_to_array_codecs(vec![
214        #[cfg(feature = "transpose")]
215        Arc::new(zarrs::array::codec::TransposeCodec::new(
216            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217        )),
218    ])
219    .bytes_to_bytes_codecs(vec![
220        #[cfg(feature = "gzip")]
221        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222        #[cfg(feature = "crc32c")]
223        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224    ])
225    // .storage_transformers(vec![].into())
226    .build(store, array_path)
227    .unwrap();
228    println!("{}", array.metadata().to_string_pretty());
229
230    let data = [
231        CustomDataTypeFloat8e3m4Element::from(2.34),
232        CustomDataTypeFloat8e3m4Element::from(3.45),
233        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235        CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236    ];
237    array.store_chunk(&[0, 0], &data).unwrap();
238
239    let data: Vec<CustomDataTypeFloat8e3m4Element> =
240        array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242    for f in &data {
243        println!(
244            "float8_e3m4: {:08b} f32: {}",
245            f.into_ne_bytes()[0],
246            f.into_f32()
247        );
248    }
249
250    assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251    assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252    assert_eq!(
253        data[2],
254        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255    );
256    assert_eq!(
257        data[3],
258        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259    );
260    assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261    assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}
examples/custom_data_type_uint4.rs (lines 211-216)
194fn main() {
195    let store = std::sync::Arc::new(MemoryStore::default());
196    let array_path = "/array";
197    let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198    let array = ArrayBuilder::new(
199        vec![6, 1], // array shape
200        vec![5, 1], // regular chunk shape
201        Arc::new(CustomDataTypeUInt4),
202        FillValue::new(fill_value.into_ne_bytes().to_vec()),
203    )
204    .array_to_array_codecs(vec![
205        #[cfg(feature = "transpose")]
206        Arc::new(zarrs::array::codec::TransposeCodec::new(
207            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208        )),
209    ])
210    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211    .bytes_to_bytes_codecs(vec![
212        #[cfg(feature = "gzip")]
213        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214        #[cfg(feature = "crc32c")]
215        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216    ])
217    // .storage_transformers(vec![].into())
218    .build(store, array_path)
219    .unwrap();
220    println!("{}", array.metadata().to_string_pretty());
221
222    let data = [
223        CustomDataTypeUInt4Element::try_from(1).unwrap(),
224        CustomDataTypeUInt4Element::try_from(2).unwrap(),
225        CustomDataTypeUInt4Element::try_from(3).unwrap(),
226        CustomDataTypeUInt4Element::try_from(4).unwrap(),
227        CustomDataTypeUInt4Element::try_from(5).unwrap(),
228    ];
229    array.store_chunk(&[0, 0], &data).unwrap();
230
231    let data: Vec<CustomDataTypeUInt4Element> =
232        array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234    for f in &data {
235        println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236    }
237
238    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240    assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241    assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242    assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243    assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245    let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}
examples/rectilinear_array_write_read.rs (lines 70-73)
10fn rectilinear_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11    use rayon::prelude::{IntoParallelIterator, ParallelIterator};
12    use zarrs::array::{ArraySubset, ZARR_NAN_F32, codec, data_type};
13    use zarrs::node::Node;
14    use zarrs::storage::store;
15
16    // Create a store
17    // let path = tempfile::TempDir::new()?;
18    // let mut store: ReadableWritableListableStorage =
19    //     Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
20    let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
21    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
22        && arg1 == "--usage-log"
23    {
24        let log_writer = Arc::new(std::sync::Mutex::new(
25            // std::io::BufWriter::new(
26            std::io::stdout(),
27            //    )
28        ));
29        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
30            chrono::Utc::now().format("[%T%.3f] ").to_string()
31        }));
32    }
33
34    // Create the root group
35    zarrs::group::GroupBuilder::new()
36        .build(store.clone(), "/")?
37        .store_metadata()?;
38
39    // Create a group with attributes
40    let group_path = "/group";
41    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
42    group
43        .attributes_mut()
44        .insert("foo".into(), serde_json::Value::String("bar".into()));
45    group.store_metadata()?;
46
47    println!(
48        "The group metadata is:\n{}\n",
49        group.metadata().to_string_pretty()
50    );
51
52    // Create an array
53    let array_path = "/group/array";
54    let array = zarrs::array::ArrayBuilder::new(
55        vec![8, 8], // array shape
56        MetadataV3::new_with_configuration(
57            "rectilinear",
58            RectilinearChunkGridConfiguration::Inline {
59                chunk_shapes: vec![
60                    // Varying: chunk sizes [1, 1, 1, 3, 2] (run-length encoded as [[1,3], 3, 2])
61                    ChunkEdgeLengths::Varying(serde_json::from_str("[[1,3], 3, 2]").unwrap()),
62                    // Scalar: regular 4-element chunks
63                    ChunkEdgeLengths::Scalar(NonZeroU64::new(4).unwrap()),
64                ],
65            },
66        ),
67        data_type::float32(),
68        ZARR_NAN_F32,
69    )
70    .bytes_to_bytes_codecs(vec![
71        #[cfg(feature = "gzip")]
72        Arc::new(codec::GzipCodec::new(5)?),
73    ])
74    .dimension_names(["y", "x"].into())
75    // .storage_transformers(vec![].into())
76    .build(store.clone(), array_path)?;
77
78    // Write array metadata to store
79    array.store_metadata()?;
80
81    // Write some chunks (in parallel)
82    (0..4).into_par_iter().try_for_each(|i| {
83        let chunk_grid = array.chunk_grid();
84        let chunk_indices = vec![i, 0];
85        if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
86            let chunk_array = ndarray::ArrayD::<f32>::from_elem(
87                chunk_shape
88                    .iter()
89                    .map(|u| u.get() as usize)
90                    .collect::<Vec<_>>(),
91                i as f32,
92            );
93            array.store_chunk(&chunk_indices, chunk_array)
94        } else {
95            Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
96                chunk_indices.to_vec(),
97            ))
98        }
99    })?;
100
101    println!(
102        "The array metadata is:\n{}\n",
103        array.metadata().to_string_pretty()
104    );
105
106    // Write a subset spanning multiple chunks, including updating chunks already written
107    array.store_array_subset(
108        &[3..6, 3..6], // start
109        ndarray::ArrayD::<f32>::from_shape_vec(
110            vec![3, 3],
111            vec![0.1f32, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
112        )?,
113    )?;
114
115    // Store elements directly, in this case set the 7th column to 123.0
116    array.store_array_subset(&[0..8, 6..7], &[123.0f32; 8])?;
117
118    // Store elements directly in a chunk, in this case set the last row of the bottom right chunk
119    array.store_chunk_subset(
120        // chunk indices
121        &[3, 1],
122        // subset within chunk
123        &[1..2, 0..4],
124        &[-4.0f32; 4],
125    )?;
126
127    // Read the whole array
128    let data_all: ndarray::ArrayD<f32> = array.retrieve_array_subset(&array.subset_all())?;
129    println!("The whole array is:\n{data_all}\n");
130
131    // Read a chunk back from the store
132    let chunk_indices = vec![1, 0];
133    let data_chunk: ndarray::ArrayD<f32> = array.retrieve_chunk(&chunk_indices)?;
134    println!("Chunk [1,0] is:\n{data_chunk}\n");
135
136    // Read the central 4x2 subset of the array
137    let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
138    let data_4x2: ndarray::ArrayD<f32> = array.retrieve_array_subset(&subset_4x2)?;
139    println!("The middle 4x2 subset is:\n{data_4x2}\n");
140
141    // Show the hierarchy
142    let node = Node::open(&store, "/").unwrap();
143    let tree = node.hierarchy_tree();
144    println!("The Zarr hierarchy tree is:\n{tree}");
145
146    Ok(())
147}
Source

pub fn subchunk_shape( &mut self, subchunk_shape: impl Into<Option<ArrayShape>>, ) -> &mut Self

Available on crate feature sharding only.

Set the subchunk (inner chunk) shape for sharding.

When set, the array will use the sharding codec. The chunk shape is the shard shape, and subchunk_shape is the shape of the subchunks within each shard.

If left unmodified or set to None, the array will not use sharding, unless configured manually via array_to_bytes_codec.

The subchunk shape must have all non-zero elements (validated during build).

§Sharding Configuration

This method uses a default ShardingCodecBuilder configuration:

  • No array-to-array codecs preceding the sharding codec
  • No bytes-to-bytes codecs following the sharding codec
  • The shard index is encoded with crc32c checksum (if the crc32c feature is enabled)

The codecs specified via array_to_array_codecs, array_to_bytes_codec, and bytes_to_bytes_codecs are used internally for encoding the subchunks within each shard.

For more advanced usage (e.g., compressing an entire shard), set array_to_bytes_codec explicitly with a sharding codec built using ShardingCodecBuilder.

§Example
let array = ArrayBuilder::new(
    vec![64, 64],    // array shape
    vec![16, 16],    // chunk (shard) shape
    data_type::float32(),
    0.0f32,
)
.subchunk_shape(vec![4, 4])  // subchunk shape within each shard
.build(store, "/array")
.unwrap();
Examples found in repository?
examples/sharded_array_write_read.rs (line 61)
10fn sharded_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11    use std::sync::Arc;
12
13    use rayon::prelude::{IntoParallelIterator, ParallelIterator};
14    use zarrs::array::{ArraySubset, codec, data_type};
15    use zarrs::node::Node;
16    use zarrs::storage::store;
17
18    // Create a store
19    // let path = tempfile::TempDir::new()?;
20    // let mut store: ReadableWritableListableStorage =
21    //     Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
22    // let mut store: ReadableWritableListableStorage = Arc::new(
23    //     zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/sharded_array_write_read.zarr")?,
24    // );
25    let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
26    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
27        && arg1 == "--usage-log"
28    {
29        let log_writer = Arc::new(std::sync::Mutex::new(
30            // std::io::BufWriter::new(
31            std::io::stdout(),
32            //    )
33        ));
34        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
35            chrono::Utc::now().format("[%T%.3f] ").to_string()
36        }));
37    }
38
39    // Create the root group
40    zarrs::group::GroupBuilder::new()
41        .build(store.clone(), "/")?
42        .store_metadata()?;
43
44    // Create a group with attributes
45    let group_path = "/group";
46    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
47    group
48        .attributes_mut()
49        .insert("foo".into(), serde_json::Value::String("bar".into()));
50    group.store_metadata()?;
51
52    // Create an array
53    let array_path = "/group/array";
54    let subchunk_shape = vec![4, 4];
55    let array = zarrs::array::ArrayBuilder::new(
56        vec![8, 8], // array shape
57        vec![4, 8], // chunk (shard) shape
58        data_type::uint16(),
59        0u16,
60    )
61    .subchunk_shape(subchunk_shape.clone())
62    .bytes_to_bytes_codecs(vec![
63        #[cfg(feature = "gzip")]
64        Arc::new(codec::GzipCodec::new(5)?),
65    ])
66    .dimension_names(["y", "x"].into())
67    // .storage_transformers(vec![].into())
68    .build(store.clone(), array_path)?;
69
70    // Write array metadata to store
71    array.store_metadata()?;
72
73    // The array metadata is
74    println!(
75        "The array metadata is:\n{}\n",
76        array.metadata().to_string_pretty()
77    );
78
79    // Use default codec options (concurrency etc)
80    let options = CodecOptions::default();
81
82    // Write some shards (in parallel)
83    (0..2).into_par_iter().try_for_each(|s| {
84        let chunk_grid = array.chunk_grid();
85        let chunk_indices = vec![s, 0];
86        if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
87            let chunk_array = ndarray::ArrayD::<u16>::from_shape_fn(
88                chunk_shape
89                    .iter()
90                    .map(|u| u.get() as usize)
91                    .collect::<Vec<_>>(),
92                |ij| {
93                    (s * chunk_shape[0].get() * chunk_shape[1].get()
94                        + ij[0] as u64 * chunk_shape[1].get()
95                        + ij[1] as u64) as u16
96                },
97            );
98            array.store_chunk(&chunk_indices, chunk_array)
99        } else {
100            Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
101                chunk_indices.to_vec(),
102            ))
103        }
104    })?;
105
106    // Read the whole array
107    let data_all: ArrayD<u16> = array.retrieve_array_subset(&array.subset_all())?;
108    println!("The whole array is:\n{data_all}\n");
109
110    // Read a shard back from the store
111    let shard_indices = vec![1, 0];
112    let data_shard: ArrayD<u16> = array.retrieve_chunk(&shard_indices)?;
113    println!("Shard [1,0] is:\n{data_shard}\n");
114
115    // Read a subchunk from the store
116    let subset_chunk_1_0 = ArraySubset::new_with_ranges(&[4..8, 0..4]);
117    let data_chunk: ArrayD<u16> = array.retrieve_array_subset(&subset_chunk_1_0)?;
118    println!("Chunk [1,0] is:\n{data_chunk}\n");
119
120    // Read the central 4x2 subset of the array
121    let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
122    let data_4x2: ArrayD<u16> = array.retrieve_array_subset(&subset_4x2)?;
123    println!("The middle 4x2 subset is:\n{data_4x2}\n");
124
125    // Decode subchunks
126    // In some cases, it might be preferable to decode subchunks in a shard directly.
127    // If using the partial decoder, then the shard index will only be read once from the store.
128    let partial_decoder = array.partial_decoder(&[0, 0])?;
129    println!("Decoded subchunks:");
130    for subchunk_subset in [
131        ArraySubset::new_with_start_shape(vec![0, 0], subchunk_shape.clone())?,
132        ArraySubset::new_with_start_shape(vec![0, 4], subchunk_shape.clone())?,
133    ] {
134        println!("{subchunk_subset}");
135        let decoded_subchunk_bytes = partial_decoder.partial_decode(&subchunk_subset, &options)?;
136        let ndarray = bytes_to_ndarray::<u16>(
137            &subchunk_shape,
138            decoded_subchunk_bytes.into_fixed()?.into_owned(),
139        )?;
140        println!("{ndarray}\n");
141    }
142
143    // Show the hierarchy
144    let node = Node::open(&store, "/").unwrap();
145    let tree = node.hierarchy_tree();
146    println!("The Zarr hierarchy tree is:\n{}", tree);
147
148    println!(
149        "The keys in the store are:\n[{}]",
150        store.list().unwrap_or_default().iter().format(", ")
151    );
152
153    Ok(())
154}
Source

pub fn attributes(&mut self, attributes: Map<String, Value>) -> &mut Self

Set the user defined attributes.

If left unmodified, the user defined attributes of the array will be empty.

Examples found in repository?
examples/data_type_optional_nested.rs (lines 26-39)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12    // Create an in-memory store
13    // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14    //     "zarrs/tests/data/v3/array_optional_nested.zarr",
15    // )?);
16    let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18    // Build the codec chains for the optional codec
19    let array = ArrayBuilder::new(
20        vec![4, 4],                                     // 4x4 array
21        vec![2, 2],                                     // 2x2 chunks
22        data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23        FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24    )
25    .dimension_names(["y", "x"].into())
26    .attributes(
27        serde_json::json!({
28            "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31  N  SN   2   3 
32  N   5   N   7 
33 SN  SN   N   N 
34 SN  SN   N   N"#,
35        })
36        .as_object()
37        .unwrap()
38        .clone(),
39    )
40    .build(store.clone(), "/array")?;
41    array.store_metadata_opt(
42        &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43    )?;
44
45    println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47    // Create some data with missing values
48    let data = ndarray::array![
49        [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50        [None, Some(Some(5u8)), None, Some(Some(7u8))],
51        [Some(None), Some(None), None, None],
52        [Some(None), Some(None), None, None],
53    ]
54    .into_dyn();
55
56    // Write the data
57    array.store_array_subset(&array.subset_all(), data.clone())?;
58    println!("Data written to array.");
59
60    // Read back the data
61    let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63    // Verify data integrity
64    assert_eq!(data, data_read);
65
66    // Display the data in a grid format
67    println!(
68        "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69    );
70    println!("    0   1   2   3");
71    for y in 0..4 {
72        print!("{} ", y);
73        for x in 0..4 {
74            match data_read[[y, x]] {
75                Some(Some(value)) => print!("{:3} ", value),
76                Some(None) => print!(" SN "),
77                None => print!("  N "),
78            }
79        }
80        println!();
81    }
82    Ok(())
83}
More examples
Hide additional examples
examples/data_type_optional.rs (lines 33-45)
18fn main() -> Result<(), Box<dyn std::error::Error>> {
19    // Create an in-memory store
20    // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
21    //     "zarrs/tests/data/v3/array_optional.zarr",
22    // )?);
23    let store = Arc::new(zarrs::storage::store::MemoryStore::new());
24
25    // Build the codec chains for the optional codec
26    let array = ArrayBuilder::new(
27        vec![4, 4],                       // 4x4 array
28        vec![2, 2],                       // 2x2 chunks
29        data_type::uint8().to_optional(), // Optional uint8
30        FillValue::new_optional_null(),   // Null fill value: [0]
31    )
32    .dimension_names(["y", "x"].into())
33    .attributes(
34        serde_json::json!({
35            "description": r#"A 4x4 array of optional uint8 values with some missing data.
36N marks missing (`None`=`null`) values:
37 0  N  2  3 
38 N  5  N  7 
39 8  9  N  N 
4012  N  N  N"#,
41        })
42        .as_object()
43        .unwrap()
44        .clone(),
45    )
46    .build(store.clone(), "/array")?;
47    array.store_metadata_opt(
48        &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
49    )?;
50
51    println!("Array metadata:\n{}", array.metadata().to_string_pretty());
52
53    // Create some data with missing values
54    let data = ndarray::array![
55        [Some(0u8), None, Some(2u8), Some(3u8)],
56        [None, Some(5u8), None, Some(7u8)],
57        [Some(8u8), Some(9u8), None, None],
58        [Some(12u8), None, None, None],
59    ]
60    .into_dyn();
61
62    // Write the data
63    array.store_array_subset(&array.subset_all(), data.clone())?;
64
65    // Read back the data
66    let data_read: ArrayD<Option<u8>> = array.retrieve_array_subset(&array.subset_all())?;
67
68    // Verify data integrity
69    assert_eq!(data, data_read);
70
71    // Display the data in a grid format
72    println!("Data grid, N marks missing (`None`=`null`) values");
73    println!("   0  1  2  3");
74    for y in 0..4 {
75        print!("{} ", y);
76        for x in 0..4 {
77            match data_read[[y, x]] {
78                Some(value) => print!("{:2} ", value),
79                None => print!(" N "),
80            }
81        }
82        println!();
83    }
84
85    // Print the raw bytes in all chunks
86    println!("Raw bytes in all chunks:");
87    let chunk_grid_shape = array.chunk_grid_shape();
88    for chunk_y in 0..chunk_grid_shape[0] {
89        for chunk_x in 0..chunk_grid_shape[1] {
90            let chunk_indices = vec![chunk_y, chunk_x];
91            let chunk_key = array.chunk_key(&chunk_indices);
92            println!("  Chunk [{}, {}] (key: {}):", chunk_y, chunk_x, chunk_key);
93
94            if let Some(chunk_bytes) = store.get(&chunk_key)? {
95                println!("    Size: {} bytes", chunk_bytes.len());
96
97                if chunk_bytes.len() >= 16 {
98                    // Parse first 8 bytes as mask size (little-endian u64)
99                    let mask_size = u64::from_le_bytes([
100                        chunk_bytes[0],
101                        chunk_bytes[1],
102                        chunk_bytes[2],
103                        chunk_bytes[3],
104                        chunk_bytes[4],
105                        chunk_bytes[5],
106                        chunk_bytes[6],
107                        chunk_bytes[7],
108                    ]) as usize;
109
110                    // Parse second 8 bytes as data size (little-endian u64)
111                    let data_size = u64::from_le_bytes([
112                        chunk_bytes[8],
113                        chunk_bytes[9],
114                        chunk_bytes[10],
115                        chunk_bytes[11],
116                        chunk_bytes[12],
117                        chunk_bytes[13],
118                        chunk_bytes[14],
119                        chunk_bytes[15],
120                    ]) as usize;
121
122                    // Display mask size header with raw bytes
123                    print!("    Mask size: 0b");
124                    for byte in &chunk_bytes[0..8] {
125                        print!("{:08b}", byte);
126                    }
127                    println!(" -> {} bytes", mask_size);
128
129                    // Display data size header with raw bytes
130                    print!("    Data size: 0b");
131                    for byte in &chunk_bytes[8..16] {
132                        print!("{:08b}", byte);
133                    }
134                    println!(" -> {} bytes", data_size);
135
136                    // Show mask and data sections separately
137                    if chunk_bytes.len() >= 16 + mask_size + data_size {
138                        let mask_start = 16;
139                        let data_start = 16 + mask_size;
140
141                        // Show mask as binary
142                        if mask_size > 0 {
143                            println!("    Mask (binary):");
144                            print!("      ");
145                            for byte in &chunk_bytes[mask_start..mask_start + mask_size] {
146                                print!("0b{:08b} ", byte);
147                            }
148                            println!();
149                        }
150
151                        // Show data as binary
152                        if data_size > 0 {
153                            println!("    Data (binary):");
154                            print!("      ");
155                            for byte in &chunk_bytes[data_start..data_start + data_size] {
156                                print!("0b{:08b} ", byte);
157                            }
158                            println!();
159                        }
160                    }
161                } else {
162                    panic!("    Chunk too small to parse headers");
163                }
164            } else {
165                println!("    Chunk missing (fill value chunk)");
166            }
167        }
168    }
169    Ok(())
170}
Source

pub fn attributes_mut(&mut self) -> &mut Map<String, Value>

Return a mutable reference to the attributes.

Source

pub fn additional_fields( &mut self, additional_fields: AdditionalFieldsV3, ) -> &mut Self

Set the additional fields.

Set additional fields not defined in the Zarr specification. Use this cautiously. In general, store user defined attributes using ArrayBuilder::attributes.

zarrs and other implementations are expected to error when opening an array with unsupported additional fields, unless they are a JSON object containing "must_understand": false.

Source

pub fn dimension_names<I, D>(&mut self, dimension_names: Option<I>) -> &mut Self
where I: IntoIterator<Item = D>, D: IntoDimensionName,

Set the dimension names.

If left unmodified, all dimension names are “unnamed”.

Examples found in repository?
examples/data_type_optional_nested.rs (line 25)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12    // Create an in-memory store
13    // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14    //     "zarrs/tests/data/v3/array_optional_nested.zarr",
15    // )?);
16    let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18    // Build the codec chains for the optional codec
19    let array = ArrayBuilder::new(
20        vec![4, 4],                                     // 4x4 array
21        vec![2, 2],                                     // 2x2 chunks
22        data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23        FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24    )
25    .dimension_names(["y", "x"].into())
26    .attributes(
27        serde_json::json!({
28            "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31  N  SN   2   3 
32  N   5   N   7 
33 SN  SN   N   N 
34 SN  SN   N   N"#,
35        })
36        .as_object()
37        .unwrap()
38        .clone(),
39    )
40    .build(store.clone(), "/array")?;
41    array.store_metadata_opt(
42        &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43    )?;
44
45    println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47    // Create some data with missing values
48    let data = ndarray::array![
49        [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50        [None, Some(Some(5u8)), None, Some(Some(7u8))],
51        [Some(None), Some(None), None, None],
52        [Some(None), Some(None), None, None],
53    ]
54    .into_dyn();
55
56    // Write the data
57    array.store_array_subset(&array.subset_all(), data.clone())?;
58    println!("Data written to array.");
59
60    // Read back the data
61    let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63    // Verify data integrity
64    assert_eq!(data, data_read);
65
66    // Display the data in a grid format
67    println!(
68        "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69    );
70    println!("    0   1   2   3");
71    for y in 0..4 {
72        print!("{} ", y);
73        for x in 0..4 {
74            match data_read[[y, x]] {
75                Some(Some(value)) => print!("{:3} ", value),
76                Some(None) => print!(" SN "),
77                None => print!("  N "),
78            }
79        }
80        println!();
81    }
82    Ok(())
83}
More examples
Hide additional examples
examples/array_write_read_string.rs (line 62)
8fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {
9    use std::sync::Arc;
10
11    use zarrs::array::{ArrayBytes, data_type};
12    use zarrs::storage::store;
13
14    // Create a store
15    // let path = tempfile::TempDir::new()?;
16    // let mut store: ReadableWritableListableStorage =
17    //     Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
18    // let mut store: ReadableWritableListableStorage = Arc::new(
19    //     zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/array_write_read.zarr")?,
20    // );
21    let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
22    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
23        && arg1 == "--usage-log"
24    {
25        let log_writer = Arc::new(std::sync::Mutex::new(
26            // std::io::BufWriter::new(
27            std::io::stdout(),
28            //    )
29        ));
30        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
31            chrono::Utc::now().format("[%T%.3f] ").to_string()
32        }));
33    }
34
35    // Create the root group
36    zarrs::group::GroupBuilder::new()
37        .build(store.clone(), "/")?
38        .store_metadata()?;
39
40    // Create a group with attributes
41    let group_path = "/group";
42    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
43    group
44        .attributes_mut()
45        .insert("foo".into(), serde_json::Value::String("bar".into()));
46    group.store_metadata()?;
47
48    println!(
49        "The group metadata is:\n{}\n",
50        group.metadata().to_string_pretty()
51    );
52
53    // Create an array
54    let array_path = "/group/array";
55    let array = zarrs::array::ArrayBuilder::new(
56        vec![4, 4], // array shape
57        vec![2, 2], // regular chunk shape
58        data_type::string(),
59        "_",
60    )
61    // .bytes_to_bytes_codecs(vec![]) // uncompressed
62    .dimension_names(["y", "x"].into())
63    // .storage_transformers(vec![].into())
64    .build(store.clone(), array_path)?;
65
66    // Write array metadata to store
67    array.store_metadata()?;
68
69    println!(
70        "The array metadata is:\n{}\n",
71        array.metadata().to_string_pretty()
72    );
73
74    // Write some chunks
75    array.store_chunk(
76        &[0, 0],
77        ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["a", "bb", "ccc", "dddd"]).unwrap(),
78    )?;
79    array.store_chunk(
80        &[0, 1],
81        ArrayD::<&str>::from_shape_vec(vec![2, 2], vec!["4444", "333", "22", "1"]).unwrap(),
82    )?;
83    let subset_all = array.subset_all();
84    let data_all: ArrayD<String> = array.retrieve_array_subset(&subset_all)?;
85    println!("store_chunk [0, 0] and [0, 1]:\n{data_all}\n");
86
87    // Write a subset spanning multiple chunks, including updating chunks already written
88    let ndarray_subset: Array2<&str> = array![["!", "@@"], ["###", "$$$$"]];
89    array.store_array_subset(&[1..3, 1..3], ndarray_subset)?;
90    let data_all: ArrayD<String> = array.retrieve_array_subset(&subset_all)?;
91    println!("store_array_subset [1..3, 1..3]:\nndarray::ArrayD<String>\n{data_all}");
92
93    // Retrieve bytes directly, convert into a single string allocation, create a &str ndarray
94    // TODO: Add a convenience function for this?
95    let data_all: ArrayBytes = array.retrieve_array_subset(&subset_all)?;
96    let (bytes, offsets) = data_all.into_variable()?.into_parts();
97    let string = String::from_utf8(bytes.into_owned())?;
98    let elements = offsets
99        .iter()
100        .tuple_windows()
101        .map(|(&curr, &next)| &string[curr..next])
102        .collect::<Vec<&str>>();
103    let ndarray = ArrayD::<&str>::from_shape_vec(subset_all.shape_usize(), elements)?;
104    println!("ndarray::ArrayD<&str>:\n{ndarray}");
105
106    Ok(())
107}
examples/rectilinear_array_write_read.rs (line 74)
10fn rectilinear_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11    use rayon::prelude::{IntoParallelIterator, ParallelIterator};
12    use zarrs::array::{ArraySubset, ZARR_NAN_F32, codec, data_type};
13    use zarrs::node::Node;
14    use zarrs::storage::store;
15
16    // Create a store
17    // let path = tempfile::TempDir::new()?;
18    // let mut store: ReadableWritableListableStorage =
19    //     Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
20    let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
21    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
22        && arg1 == "--usage-log"
23    {
24        let log_writer = Arc::new(std::sync::Mutex::new(
25            // std::io::BufWriter::new(
26            std::io::stdout(),
27            //    )
28        ));
29        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
30            chrono::Utc::now().format("[%T%.3f] ").to_string()
31        }));
32    }
33
34    // Create the root group
35    zarrs::group::GroupBuilder::new()
36        .build(store.clone(), "/")?
37        .store_metadata()?;
38
39    // Create a group with attributes
40    let group_path = "/group";
41    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
42    group
43        .attributes_mut()
44        .insert("foo".into(), serde_json::Value::String("bar".into()));
45    group.store_metadata()?;
46
47    println!(
48        "The group metadata is:\n{}\n",
49        group.metadata().to_string_pretty()
50    );
51
52    // Create an array
53    let array_path = "/group/array";
54    let array = zarrs::array::ArrayBuilder::new(
55        vec![8, 8], // array shape
56        MetadataV3::new_with_configuration(
57            "rectilinear",
58            RectilinearChunkGridConfiguration::Inline {
59                chunk_shapes: vec![
60                    // Varying: chunk sizes [1, 1, 1, 3, 2] (run-length encoded as [[1,3], 3, 2])
61                    ChunkEdgeLengths::Varying(serde_json::from_str("[[1,3], 3, 2]").unwrap()),
62                    // Scalar: regular 4-element chunks
63                    ChunkEdgeLengths::Scalar(NonZeroU64::new(4).unwrap()),
64                ],
65            },
66        ),
67        data_type::float32(),
68        ZARR_NAN_F32,
69    )
70    .bytes_to_bytes_codecs(vec![
71        #[cfg(feature = "gzip")]
72        Arc::new(codec::GzipCodec::new(5)?),
73    ])
74    .dimension_names(["y", "x"].into())
75    // .storage_transformers(vec![].into())
76    .build(store.clone(), array_path)?;
77
78    // Write array metadata to store
79    array.store_metadata()?;
80
81    // Write some chunks (in parallel)
82    (0..4).into_par_iter().try_for_each(|i| {
83        let chunk_grid = array.chunk_grid();
84        let chunk_indices = vec![i, 0];
85        if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
86            let chunk_array = ndarray::ArrayD::<f32>::from_elem(
87                chunk_shape
88                    .iter()
89                    .map(|u| u.get() as usize)
90                    .collect::<Vec<_>>(),
91                i as f32,
92            );
93            array.store_chunk(&chunk_indices, chunk_array)
94        } else {
95            Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
96                chunk_indices.to_vec(),
97            ))
98        }
99    })?;
100
101    println!(
102        "The array metadata is:\n{}\n",
103        array.metadata().to_string_pretty()
104    );
105
106    // Write a subset spanning multiple chunks, including updating chunks already written
107    array.store_array_subset(
108        &[3..6, 3..6], // start
109        ndarray::ArrayD::<f32>::from_shape_vec(
110            vec![3, 3],
111            vec![0.1f32, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
112        )?,
113    )?;
114
115    // Store elements directly, in this case set the 7th column to 123.0
116    array.store_array_subset(&[0..8, 6..7], &[123.0f32; 8])?;
117
118    // Store elements directly in a chunk, in this case set the last row of the bottom right chunk
119    array.store_chunk_subset(
120        // chunk indices
121        &[3, 1],
122        // subset within chunk
123        &[1..2, 0..4],
124        &[-4.0f32; 4],
125    )?;
126
127    // Read the whole array
128    let data_all: ndarray::ArrayD<f32> = array.retrieve_array_subset(&array.subset_all())?;
129    println!("The whole array is:\n{data_all}\n");
130
131    // Read a chunk back from the store
132    let chunk_indices = vec![1, 0];
133    let data_chunk: ndarray::ArrayD<f32> = array.retrieve_chunk(&chunk_indices)?;
134    println!("Chunk [1,0] is:\n{data_chunk}\n");
135
136    // Read the central 4x2 subset of the array
137    let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
138    let data_4x2: ndarray::ArrayD<f32> = array.retrieve_array_subset(&subset_4x2)?;
139    println!("The middle 4x2 subset is:\n{data_4x2}\n");
140
141    // Show the hierarchy
142    let node = Node::open(&store, "/").unwrap();
143    let tree = node.hierarchy_tree();
144    println!("The Zarr hierarchy tree is:\n{tree}");
145
146    Ok(())
147}
examples/array_write_read.rs (line 63)
8fn array_write_read() -> Result<(), Box<dyn std::error::Error>> {
9    use std::sync::Arc;
10
11    use zarrs::array::{ArraySubset, ZARR_NAN_F32, data_type};
12    use zarrs::node::Node;
13    use zarrs::storage::store;
14
15    // Create a store
16    // let path = tempfile::TempDir::new()?;
17    // let mut store: ReadableWritableListableStorage =
18    //     Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
19    // let mut store: ReadableWritableListableStorage = Arc::new(
20    //     zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/array_write_read.zarr")?,
21    // );
22    let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
23    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
24        && arg1 == "--usage-log"
25    {
26        let log_writer = Arc::new(std::sync::Mutex::new(
27            // std::io::BufWriter::new(
28            std::io::stdout(),
29            //    )
30        ));
31        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
32            chrono::Utc::now().format("[%T%.3f] ").to_string()
33        }));
34    }
35
36    // Create the root group
37    zarrs::group::GroupBuilder::new()
38        .build(store.clone(), "/")?
39        .store_metadata()?;
40
41    // Create a group with attributes
42    let group_path = "/group";
43    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
44    group
45        .attributes_mut()
46        .insert("foo".into(), serde_json::Value::String("bar".into()));
47    group.store_metadata()?;
48
49    println!(
50        "The group metadata is:\n{}\n",
51        group.metadata().to_string_pretty()
52    );
53
54    // Create an array
55    let array_path = "/group/array";
56    let array = zarrs::array::ArrayBuilder::new(
57        vec![8, 8], // array shape
58        vec![4, 4], // regular chunk shape
59        data_type::float32(),
60        ZARR_NAN_F32,
61    )
62    // .bytes_to_bytes_codecs(vec![]) // uncompressed
63    .dimension_names(["y", "x"].into())
64    // .storage_transformers(vec![].into())
65    .build(store.clone(), array_path)?;
66
67    // Write array metadata to store
68    array.store_metadata()?;
69
70    println!(
71        "The array metadata is:\n{}\n",
72        array.metadata().to_string_pretty()
73    );
74
75    // Write some chunks
76    (0..2).into_par_iter().try_for_each(|i| {
77        let chunk_indices: Vec<u64> = vec![0, i];
78        let chunk_subset = array.chunk_grid().subset(&chunk_indices)?.ok_or_else(|| {
79            zarrs::array::ArrayError::InvalidChunkGridIndicesError(chunk_indices.to_vec())
80        })?;
81        array.store_chunk(
82            &chunk_indices,
83            vec![i as f32 * 0.1; chunk_subset.num_elements() as usize],
84        )
85    })?;
86
87    let subset_all = array.subset_all();
88    let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
89    println!("store_chunk [0, 0] and [0, 1]:\n{data_all:+4.1}\n");
90
91    // Store multiple chunks
92    array.store_chunks(
93        &[1..2, 0..2],
94        &[
95            //
96            1.0f32, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
97            //
98            1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
99        ],
100    )?;
101    let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
102    println!("store_chunks [1..2, 0..2]:\n{data_all:+4.1}\n");
103
104    // Write a subset spanning multiple chunks, including updating chunks already written
105    array.store_array_subset(
106        &[3..6, 3..6],
107        &[-3.3f32, -3.4, -3.5, -4.3, -4.4, -4.5, -5.3, -5.4, -5.5],
108    )?;
109    let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
110    println!("store_array_subset [3..6, 3..6]:\n{data_all:+4.1}\n");
111
112    // Store array subset
113    array.store_array_subset(
114        &[0..8, 6..7],
115        &[-0.6f32, -1.6, -2.6, -3.6, -4.6, -5.6, -6.6, -7.6],
116    )?;
117    let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
118    println!("store_array_subset [0..8, 6..7]:\n{data_all:+4.1}\n");
119
120    // Store chunk subset
121    array.store_chunk_subset(
122        // chunk indices
123        &[1, 1],
124        // subset within chunk
125        &[3..4, 0..4],
126        &[-7.4f32, -7.5, -7.6, -7.7],
127    )?;
128    let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
129    println!("store_chunk_subset [3..4, 0..4] of chunk [1, 1]:\n{data_all:+4.1}\n");
130
131    // Erase a chunk
132    array.erase_chunk(&[0, 0])?;
133    let data_all: ArrayD<f32> = array.retrieve_array_subset(&subset_all)?;
134    println!("erase_chunk [0, 0]:\n{data_all:+4.1}\n");
135
136    // Read a chunk
137    let chunk_indices = vec![0, 1];
138    let data_chunk: ArrayD<f32> = array.retrieve_chunk(&chunk_indices)?;
139    println!("retrieve_chunk [0, 1]:\n{data_chunk:+4.1}\n");
140
141    // Read chunks
142    let chunks = ArraySubset::new_with_ranges(&[0..2, 1..2]);
143    let data_chunks: ArrayD<f32> = array.retrieve_chunks(&chunks)?;
144    println!("retrieve_chunks [0..2, 1..2]:\n{data_chunks:+4.1}\n");
145
146    // Retrieve an array subset
147    let subset = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
148    let data_subset: ArrayD<f32> = array.retrieve_array_subset(&subset)?;
149    println!("retrieve_array_subset [2..6, 3..5]:\n{data_subset:+4.1}\n");
150
151    // Show the hierarchy
152    let node = Node::open(&store, "/").unwrap();
153    let tree = node.hierarchy_tree();
154    println!("hierarchy_tree:\n{}", tree);
155
156    Ok(())
157}
examples/sharded_array_write_read.rs (line 66)
10fn sharded_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
11    use std::sync::Arc;
12
13    use rayon::prelude::{IntoParallelIterator, ParallelIterator};
14    use zarrs::array::{ArraySubset, codec, data_type};
15    use zarrs::node::Node;
16    use zarrs::storage::store;
17
18    // Create a store
19    // let path = tempfile::TempDir::new()?;
20    // let mut store: ReadableWritableListableStorage =
21    //     Arc::new(zarrs::filesystem::FilesystemStore::new(path.path())?);
22    // let mut store: ReadableWritableListableStorage = Arc::new(
23    //     zarrs::filesystem::FilesystemStore::new("zarrs/tests/data/sharded_array_write_read.zarr")?,
24    // );
25    let mut store: ReadableWritableListableStorage = Arc::new(store::MemoryStore::new());
26    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
27        && arg1 == "--usage-log"
28    {
29        let log_writer = Arc::new(std::sync::Mutex::new(
30            // std::io::BufWriter::new(
31            std::io::stdout(),
32            //    )
33        ));
34        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
35            chrono::Utc::now().format("[%T%.3f] ").to_string()
36        }));
37    }
38
39    // Create the root group
40    zarrs::group::GroupBuilder::new()
41        .build(store.clone(), "/")?
42        .store_metadata()?;
43
44    // Create a group with attributes
45    let group_path = "/group";
46    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
47    group
48        .attributes_mut()
49        .insert("foo".into(), serde_json::Value::String("bar".into()));
50    group.store_metadata()?;
51
52    // Create an array
53    let array_path = "/group/array";
54    let subchunk_shape = vec![4, 4];
55    let array = zarrs::array::ArrayBuilder::new(
56        vec![8, 8], // array shape
57        vec![4, 8], // chunk (shard) shape
58        data_type::uint16(),
59        0u16,
60    )
61    .subchunk_shape(subchunk_shape.clone())
62    .bytes_to_bytes_codecs(vec![
63        #[cfg(feature = "gzip")]
64        Arc::new(codec::GzipCodec::new(5)?),
65    ])
66    .dimension_names(["y", "x"].into())
67    // .storage_transformers(vec![].into())
68    .build(store.clone(), array_path)?;
69
70    // Write array metadata to store
71    array.store_metadata()?;
72
73    // The array metadata is
74    println!(
75        "The array metadata is:\n{}\n",
76        array.metadata().to_string_pretty()
77    );
78
79    // Use default codec options (concurrency etc)
80    let options = CodecOptions::default();
81
82    // Write some shards (in parallel)
83    (0..2).into_par_iter().try_for_each(|s| {
84        let chunk_grid = array.chunk_grid();
85        let chunk_indices = vec![s, 0];
86        if let Some(chunk_shape) = chunk_grid.chunk_shape(&chunk_indices)? {
87            let chunk_array = ndarray::ArrayD::<u16>::from_shape_fn(
88                chunk_shape
89                    .iter()
90                    .map(|u| u.get() as usize)
91                    .collect::<Vec<_>>(),
92                |ij| {
93                    (s * chunk_shape[0].get() * chunk_shape[1].get()
94                        + ij[0] as u64 * chunk_shape[1].get()
95                        + ij[1] as u64) as u16
96                },
97            );
98            array.store_chunk(&chunk_indices, chunk_array)
99        } else {
100            Err(zarrs::array::ArrayError::InvalidChunkGridIndicesError(
101                chunk_indices.to_vec(),
102            ))
103        }
104    })?;
105
106    // Read the whole array
107    let data_all: ArrayD<u16> = array.retrieve_array_subset(&array.subset_all())?;
108    println!("The whole array is:\n{data_all}\n");
109
110    // Read a shard back from the store
111    let shard_indices = vec![1, 0];
112    let data_shard: ArrayD<u16> = array.retrieve_chunk(&shard_indices)?;
113    println!("Shard [1,0] is:\n{data_shard}\n");
114
115    // Read a subchunk from the store
116    let subset_chunk_1_0 = ArraySubset::new_with_ranges(&[4..8, 0..4]);
117    let data_chunk: ArrayD<u16> = array.retrieve_array_subset(&subset_chunk_1_0)?;
118    println!("Chunk [1,0] is:\n{data_chunk}\n");
119
120    // Read the central 4x2 subset of the array
121    let subset_4x2 = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
122    let data_4x2: ArrayD<u16> = array.retrieve_array_subset(&subset_4x2)?;
123    println!("The middle 4x2 subset is:\n{data_4x2}\n");
124
125    // Decode subchunks
126    // In some cases, it might be preferable to decode subchunks in a shard directly.
127    // If using the partial decoder, then the shard index will only be read once from the store.
128    let partial_decoder = array.partial_decoder(&[0, 0])?;
129    println!("Decoded subchunks:");
130    for subchunk_subset in [
131        ArraySubset::new_with_start_shape(vec![0, 0], subchunk_shape.clone())?,
132        ArraySubset::new_with_start_shape(vec![0, 4], subchunk_shape.clone())?,
133    ] {
134        println!("{subchunk_subset}");
135        let decoded_subchunk_bytes = partial_decoder.partial_decode(&subchunk_subset, &options)?;
136        let ndarray = bytes_to_ndarray::<u16>(
137            &subchunk_shape,
138            decoded_subchunk_bytes.into_fixed()?.into_owned(),
139        )?;
140        println!("{ndarray}\n");
141    }
142
143    // Show the hierarchy
144    let node = Node::open(&store, "/").unwrap();
145    let tree = node.hierarchy_tree();
146    println!("The Zarr hierarchy tree is:\n{}", tree);
147
148    println!(
149        "The keys in the store are:\n[{}]",
150        store.list().unwrap_or_default().iter().format(", ")
151    );
152
153    Ok(())
154}
examples/data_type_optional.rs (line 32)
18fn main() -> Result<(), Box<dyn std::error::Error>> {
19    // Create an in-memory store
20    // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
21    //     "zarrs/tests/data/v3/array_optional.zarr",
22    // )?);
23    let store = Arc::new(zarrs::storage::store::MemoryStore::new());
24
25    // Build the codec chains for the optional codec
26    let array = ArrayBuilder::new(
27        vec![4, 4],                       // 4x4 array
28        vec![2, 2],                       // 2x2 chunks
29        data_type::uint8().to_optional(), // Optional uint8
30        FillValue::new_optional_null(),   // Null fill value: [0]
31    )
32    .dimension_names(["y", "x"].into())
33    .attributes(
34        serde_json::json!({
35            "description": r#"A 4x4 array of optional uint8 values with some missing data.
36N marks missing (`None`=`null`) values:
37 0  N  2  3 
38 N  5  N  7 
39 8  9  N  N 
4012  N  N  N"#,
41        })
42        .as_object()
43        .unwrap()
44        .clone(),
45    )
46    .build(store.clone(), "/array")?;
47    array.store_metadata_opt(
48        &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
49    )?;
50
51    println!("Array metadata:\n{}", array.metadata().to_string_pretty());
52
53    // Create some data with missing values
54    let data = ndarray::array![
55        [Some(0u8), None, Some(2u8), Some(3u8)],
56        [None, Some(5u8), None, Some(7u8)],
57        [Some(8u8), Some(9u8), None, None],
58        [Some(12u8), None, None, None],
59    ]
60    .into_dyn();
61
62    // Write the data
63    array.store_array_subset(&array.subset_all(), data.clone())?;
64
65    // Read back the data
66    let data_read: ArrayD<Option<u8>> = array.retrieve_array_subset(&array.subset_all())?;
67
68    // Verify data integrity
69    assert_eq!(data, data_read);
70
71    // Display the data in a grid format
72    println!("Data grid, N marks missing (`None`=`null`) values");
73    println!("   0  1  2  3");
74    for y in 0..4 {
75        print!("{} ", y);
76        for x in 0..4 {
77            match data_read[[y, x]] {
78                Some(value) => print!("{:2} ", value),
79                None => print!(" N "),
80            }
81        }
82        println!();
83    }
84
85    // Print the raw bytes in all chunks
86    println!("Raw bytes in all chunks:");
87    let chunk_grid_shape = array.chunk_grid_shape();
88    for chunk_y in 0..chunk_grid_shape[0] {
89        for chunk_x in 0..chunk_grid_shape[1] {
90            let chunk_indices = vec![chunk_y, chunk_x];
91            let chunk_key = array.chunk_key(&chunk_indices);
92            println!("  Chunk [{}, {}] (key: {}):", chunk_y, chunk_x, chunk_key);
93
94            if let Some(chunk_bytes) = store.get(&chunk_key)? {
95                println!("    Size: {} bytes", chunk_bytes.len());
96
97                if chunk_bytes.len() >= 16 {
98                    // Parse first 8 bytes as mask size (little-endian u64)
99                    let mask_size = u64::from_le_bytes([
100                        chunk_bytes[0],
101                        chunk_bytes[1],
102                        chunk_bytes[2],
103                        chunk_bytes[3],
104                        chunk_bytes[4],
105                        chunk_bytes[5],
106                        chunk_bytes[6],
107                        chunk_bytes[7],
108                    ]) as usize;
109
110                    // Parse second 8 bytes as data size (little-endian u64)
111                    let data_size = u64::from_le_bytes([
112                        chunk_bytes[8],
113                        chunk_bytes[9],
114                        chunk_bytes[10],
115                        chunk_bytes[11],
116                        chunk_bytes[12],
117                        chunk_bytes[13],
118                        chunk_bytes[14],
119                        chunk_bytes[15],
120                    ]) as usize;
121
122                    // Display mask size header with raw bytes
123                    print!("    Mask size: 0b");
124                    for byte in &chunk_bytes[0..8] {
125                        print!("{:08b}", byte);
126                    }
127                    println!(" -> {} bytes", mask_size);
128
129                    // Display data size header with raw bytes
130                    print!("    Data size: 0b");
131                    for byte in &chunk_bytes[8..16] {
132                        print!("{:08b}", byte);
133                    }
134                    println!(" -> {} bytes", data_size);
135
136                    // Show mask and data sections separately
137                    if chunk_bytes.len() >= 16 + mask_size + data_size {
138                        let mask_start = 16;
139                        let data_start = 16 + mask_size;
140
141                        // Show mask as binary
142                        if mask_size > 0 {
143                            println!("    Mask (binary):");
144                            print!("      ");
145                            for byte in &chunk_bytes[mask_start..mask_start + mask_size] {
146                                print!("0b{:08b} ", byte);
147                            }
148                            println!();
149                        }
150
151                        // Show data as binary
152                        if data_size > 0 {
153                            println!("    Data (binary):");
154                            print!("      ");
155                            for byte in &chunk_bytes[data_start..data_start + data_size] {
156                                print!("0b{:08b} ", byte);
157                            }
158                            println!();
159                        }
160                    }
161                } else {
162                    panic!("    Chunk too small to parse headers");
163                }
164            } else {
165                println!("    Chunk missing (fill value chunk)");
166            }
167        }
168    }
169    Ok(())
170}
Source

pub fn storage_transformers( &mut self, storage_transformers: StorageTransformerChain, ) -> &mut Self

Set the storage transformers.

If left unmodified, there are no storage transformers.

Source

pub fn build_metadata(&self) -> Result<ArrayMetadataV3, ArrayCreateError>

Get the metadata of an array that would be created with the current builder state.

§Errors

Returns an ArrayCreateError if this metadata is invalid/unsupported by zarrs.

Source

pub fn build<TStorage: ?Sized>( &self, storage: Arc<TStorage>, path: &str, ) -> Result<Array<TStorage>, ArrayCreateError>

Build into an Array.

§Errors

Returns ArrayCreateError if there is an error creating the array. This can be due to a storage error, an invalid path, or a problem with array configuration.

Examples found in repository?
examples/custom_data_type_variable_size.rs (line 179)
157fn main() {
158    let store = std::sync::Arc::new(MemoryStore::default());
159    let array_path = "/array";
160    let array = ArrayBuilder::new(
161        vec![4, 1], // array shape
162        vec![3, 1], // regular chunk shape
163        Arc::new(CustomDataTypeVariableSize),
164        [],
165    )
166    .array_to_array_codecs(vec![
167        #[cfg(feature = "transpose")]
168        Arc::new(zarrs::array::codec::TransposeCodec::new(
169            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
170        )),
171    ])
172    .bytes_to_bytes_codecs(vec![
173        #[cfg(feature = "gzip")]
174        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
175        #[cfg(feature = "crc32c")]
176        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
177    ])
178    // .storage_transformers(vec![].into())
179    .build(store, array_path)
180    .unwrap();
181    println!("{}", array.metadata().to_string_pretty());
182
183    let data = [
184        CustomDataTypeVariableSizeElement::from(Some(1.0)),
185        CustomDataTypeVariableSizeElement::from(None),
186        CustomDataTypeVariableSizeElement::from(Some(3.0)),
187    ];
188    array.store_chunk(&[0, 0], &data).unwrap();
189
190    let data: Vec<CustomDataTypeVariableSizeElement> =
191        array.retrieve_array_subset(&array.subset_all()).unwrap();
192
193    assert_eq!(data[0], CustomDataTypeVariableSizeElement::from(Some(1.0)));
194    assert_eq!(data[1], CustomDataTypeVariableSizeElement::from(None));
195    assert_eq!(data[2], CustomDataTypeVariableSizeElement::from(Some(3.0)));
196    assert_eq!(data[3], CustomDataTypeVariableSizeElement::from(None));
197
198    println!("{data:#?}");
199}
More examples
Hide additional examples
examples/custom_data_type_fixed_size.rs (line 303)
280fn main() {
281    let store = std::sync::Arc::new(MemoryStore::default());
282    let array_path = "/array";
283    let fill_value = CustomDataTypeFixedSizeElement { x: 1, y: 2.3 };
284    let array = ArrayBuilder::new(
285        vec![4, 1], // array shape
286        vec![2, 1], // regular chunk shape
287        Arc::new(CustomDataTypeFixedSize),
288        FillValue::new(fill_value.to_ne_bytes().to_vec()),
289    )
290    .array_to_array_codecs(vec![
291        #[cfg(feature = "transpose")]
292        Arc::new(zarrs::array::codec::TransposeCodec::new(
293            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
294        )),
295    ])
296    .bytes_to_bytes_codecs(vec![
297        #[cfg(feature = "gzip")]
298        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
299        #[cfg(feature = "crc32c")]
300        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
301    ])
302    // .storage_transformers(vec![].into())
303    .build(store, array_path)
304    .unwrap();
305    println!("{}", array.metadata().to_string_pretty());
306
307    let data = [
308        CustomDataTypeFixedSizeElement { x: 3, y: 4.5 },
309        CustomDataTypeFixedSizeElement { x: 6, y: 7.8 },
310    ];
311    array.store_chunk(&[0, 0], &data).unwrap();
312
313    let data: Vec<CustomDataTypeFixedSizeElement> =
314        array.retrieve_array_subset(&array.subset_all()).unwrap();
315
316    assert_eq!(data[0], CustomDataTypeFixedSizeElement { x: 3, y: 4.5 });
317    assert_eq!(data[1], CustomDataTypeFixedSizeElement { x: 6, y: 7.8 });
318    assert_eq!(data[2], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
319    assert_eq!(data[3], CustomDataTypeFixedSizeElement { x: 1, y: 2.3 });
320
321    println!("{data:#?}");
322}
examples/custom_data_type_uint12.rs (line 216)
192fn main() {
193    let store = std::sync::Arc::new(MemoryStore::default());
194    let array_path = "/array";
195    let fill_value = CustomDataTypeUInt12Element::try_from(15).unwrap();
196    let array = ArrayBuilder::new(
197        vec![4096, 1], // array shape
198        vec![5, 1],    // regular chunk shape
199        Arc::new(CustomDataTypeUInt12),
200        FillValue::new(fill_value.into_le_bytes().to_vec()),
201    )
202    .array_to_array_codecs(vec![
203        #[cfg(feature = "transpose")]
204        Arc::new(zarrs::array::codec::TransposeCodec::new(
205            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
206        )),
207    ])
208    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
209    .bytes_to_bytes_codecs(vec![
210        #[cfg(feature = "gzip")]
211        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
212        #[cfg(feature = "crc32c")]
213        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
214    ])
215    // .storage_transformers(vec![].into())
216    .build(store, array_path)
217    .unwrap();
218    println!("{}", array.metadata().to_string_pretty());
219
220    let data: Vec<CustomDataTypeUInt12Element> = (0..4096)
221        .map(|i| CustomDataTypeUInt12Element::try_from(i).unwrap())
222        .collect();
223
224    array
225        .store_array_subset(&array.subset_all(), &data)
226        .unwrap();
227
228    let mut data: Vec<CustomDataTypeUInt12Element> =
229        array.retrieve_array_subset(&array.subset_all()).unwrap();
230
231    for (i, d) in data.drain(0..4096).enumerate() {
232        let element = CustomDataTypeUInt12Element::try_from(i as u64).unwrap();
233        assert_eq!(d, element);
234        let element_pd: Vec<CustomDataTypeUInt12Element> = array
235            .retrieve_array_subset(&[(i as u64)..i as u64 + 1, 0..1])
236            .unwrap();
237        assert_eq!(element_pd[0], element);
238    }
239}
examples/custom_data_type_float8_e3m4.rs (line 226)
203fn main() {
204    let store = std::sync::Arc::new(MemoryStore::default());
205    let array_path = "/array";
206    let fill_value = CustomDataTypeFloat8e3m4Element::from(1.23);
207    let array = ArrayBuilder::new(
208        vec![6, 1], // array shape
209        vec![5, 1], // regular chunk shape
210        Arc::new(CustomDataTypeFloat8e3m4),
211        FillValue::new(fill_value.into_ne_bytes().to_vec()),
212    )
213    .array_to_array_codecs(vec![
214        #[cfg(feature = "transpose")]
215        Arc::new(zarrs::array::codec::TransposeCodec::new(
216            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
217        )),
218    ])
219    .bytes_to_bytes_codecs(vec![
220        #[cfg(feature = "gzip")]
221        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
222        #[cfg(feature = "crc32c")]
223        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
224    ])
225    // .storage_transformers(vec![].into())
226    .build(store, array_path)
227    .unwrap();
228    println!("{}", array.metadata().to_string_pretty());
229
230    let data = [
231        CustomDataTypeFloat8e3m4Element::from(2.34),
232        CustomDataTypeFloat8e3m4Element::from(3.45),
233        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY),
234        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY),
235        CustomDataTypeFloat8e3m4Element::from(f32::NAN),
236    ];
237    array.store_chunk(&[0, 0], &data).unwrap();
238
239    let data: Vec<CustomDataTypeFloat8e3m4Element> =
240        array.retrieve_array_subset(&array.subset_all()).unwrap();
241
242    for f in &data {
243        println!(
244            "float8_e3m4: {:08b} f32: {}",
245            f.into_ne_bytes()[0],
246            f.into_f32()
247        );
248    }
249
250    assert_eq!(data[0], CustomDataTypeFloat8e3m4Element::from(2.34));
251    assert_eq!(data[1], CustomDataTypeFloat8e3m4Element::from(3.45));
252    assert_eq!(
253        data[2],
254        CustomDataTypeFloat8e3m4Element::from(f32::INFINITY)
255    );
256    assert_eq!(
257        data[3],
258        CustomDataTypeFloat8e3m4Element::from(f32::NEG_INFINITY)
259    );
260    assert_eq!(data[4], CustomDataTypeFloat8e3m4Element::from(f32::NAN));
261    assert_eq!(data[5], CustomDataTypeFloat8e3m4Element::from(1.23));
262}
examples/custom_data_type_uint4.rs (line 218)
194fn main() {
195    let store = std::sync::Arc::new(MemoryStore::default());
196    let array_path = "/array";
197    let fill_value = CustomDataTypeUInt4Element::try_from(15).unwrap();
198    let array = ArrayBuilder::new(
199        vec![6, 1], // array shape
200        vec![5, 1], // regular chunk shape
201        Arc::new(CustomDataTypeUInt4),
202        FillValue::new(fill_value.into_ne_bytes().to_vec()),
203    )
204    .array_to_array_codecs(vec![
205        #[cfg(feature = "transpose")]
206        Arc::new(zarrs::array::codec::TransposeCodec::new(
207            zarrs::array::codec::array_to_array::transpose::TransposeOrder::new(&[1, 0]).unwrap(),
208        )),
209    ])
210    .array_to_bytes_codec(Arc::new(zarrs::array::codec::PackBitsCodec::default()))
211    .bytes_to_bytes_codecs(vec![
212        #[cfg(feature = "gzip")]
213        Arc::new(zarrs::array::codec::GzipCodec::new(5).unwrap()),
214        #[cfg(feature = "crc32c")]
215        Arc::new(zarrs::array::codec::Crc32cCodec::new()),
216    ])
217    // .storage_transformers(vec![].into())
218    .build(store, array_path)
219    .unwrap();
220    println!("{}", array.metadata().to_string_pretty());
221
222    let data = [
223        CustomDataTypeUInt4Element::try_from(1).unwrap(),
224        CustomDataTypeUInt4Element::try_from(2).unwrap(),
225        CustomDataTypeUInt4Element::try_from(3).unwrap(),
226        CustomDataTypeUInt4Element::try_from(4).unwrap(),
227        CustomDataTypeUInt4Element::try_from(5).unwrap(),
228    ];
229    array.store_chunk(&[0, 0], &data).unwrap();
230
231    let data: Vec<CustomDataTypeUInt4Element> =
232        array.retrieve_array_subset(&array.subset_all()).unwrap();
233
234    for f in &data {
235        println!("uint4: {:08b} u8: {}", f.into_u8(), f.into_u8());
236    }
237
238    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(1).unwrap());
239    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(2).unwrap());
240    assert_eq!(data[2], CustomDataTypeUInt4Element::try_from(3).unwrap());
241    assert_eq!(data[3], CustomDataTypeUInt4Element::try_from(4).unwrap());
242    assert_eq!(data[4], CustomDataTypeUInt4Element::try_from(5).unwrap());
243    assert_eq!(data[5], CustomDataTypeUInt4Element::try_from(15).unwrap());
244
245    let data: Vec<CustomDataTypeUInt4Element> = array.retrieve_array_subset(&[1..3, 0..1]).unwrap();
246    assert_eq!(data[0], CustomDataTypeUInt4Element::try_from(2).unwrap());
247    assert_eq!(data[1], CustomDataTypeUInt4Element::try_from(3).unwrap());
248}
examples/data_type_optional_nested.rs (line 40)
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12    // Create an in-memory store
13    // let store = Arc::new(zarrs::filesystem::FilesystemStore::new(
14    //     "zarrs/tests/data/v3/array_optional_nested.zarr",
15    // )?);
16    let store = Arc::new(zarrs::storage::store::MemoryStore::new());
17
18    // Build the codec chains for the optional codec
19    let array = ArrayBuilder::new(
20        vec![4, 4],                                     // 4x4 array
21        vec![2, 2],                                     // 2x2 chunks
22        data_type::uint8().to_optional().to_optional(), // Optional optional uint8 => Option<Option<u8>>
23        FillValue::new_optional_null().into_optional(), // Fill value => Some(None)
24    )
25    .dimension_names(["y", "x"].into())
26    .attributes(
27        serde_json::json!({
28            "description": r#"A 4x4 array of optional optional uint8 values with some missing data.
29The fill value is null on the inner optional layer, i.e. Some(None).
30N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values:
31  N  SN   2   3 
32  N   5   N   7 
33 SN  SN   N   N 
34 SN  SN   N   N"#,
35        })
36        .as_object()
37        .unwrap()
38        .clone(),
39    )
40    .build(store.clone(), "/array")?;
41    array.store_metadata_opt(
42        &zarrs::array::ArrayMetadataOptions::default().with_include_zarrs_metadata(false),
43    )?;
44
45    println!("Array metadata:\n{}", array.metadata().to_string_pretty());
46
47    // Create some data with missing values
48    let data = ndarray::array![
49        [None, Some(None), Some(Some(2u8)), Some(Some(3u8))],
50        [None, Some(Some(5u8)), None, Some(Some(7u8))],
51        [Some(None), Some(None), None, None],
52        [Some(None), Some(None), None, None],
53    ]
54    .into_dyn();
55
56    // Write the data
57    array.store_array_subset(&array.subset_all(), data.clone())?;
58    println!("Data written to array.");
59
60    // Read back the data
61    let data_read: ArrayD<Option<Option<u8>>> = array.retrieve_array_subset(&array.subset_all())?;
62
63    // Verify data integrity
64    assert_eq!(data, data_read);
65
66    // Display the data in a grid format
67    println!(
68        "Data grid. N marks missing (`None`=`null`) values. SN marks `Some(None)`=`[null]` values"
69    );
70    println!("    0   1   2   3");
71    for y in 0..4 {
72        print!("{} ", y);
73        for x in 0..4 {
74            match data_read[[y, x]] {
75                Some(Some(value)) => print!("{:3} ", value),
76                Some(None) => print!(" SN "),
77                None => print!("  N "),
78            }
79        }
80        println!();
81    }
82    Ok(())
83}
Source

pub fn build_arc<TStorage: ?Sized>( &self, storage: Arc<TStorage>, path: &str, ) -> Result<Arc<Array<TStorage>>, ArrayCreateError>

Build into an Arc<Array>.

§Errors

Returns ArrayCreateError if there is an error creating the array. This can be due to a storage error, an invalid path, or a problem with array configuration.

Examples found in repository?
examples/async_array_write_read.rs (line 62)
8async fn async_array_write_read() -> Result<(), Box<dyn std::error::Error>> {
9    use std::sync::Arc;
10
11    use futures::StreamExt;
12    use zarrs::array::{ArraySubset, ZARR_NAN_F32, data_type};
13    use zarrs::node::Node;
14
15    // Create a store
16    let mut store: AsyncReadableWritableListableStorage = Arc::new(
17        zarrs_object_store::AsyncObjectStore::new(object_store::memory::InMemory::new()),
18    );
19    if let Some(arg1) = std::env::args().collect::<Vec<_>>().get(1)
20        && arg1 == "--usage-log"
21    {
22        let log_writer = Arc::new(std::sync::Mutex::new(
23            // std::io::BufWriter::new(
24            std::io::stdout(),
25            //    )
26        ));
27        store = Arc::new(UsageLogStorageAdapter::new(store, log_writer, || {
28            chrono::Utc::now().format("[%T%.3f] ").to_string()
29        }));
30    }
31
32    // Create the root group
33    zarrs::group::GroupBuilder::new()
34        .build(store.clone(), "/")?
35        .async_store_metadata()
36        .await?;
37
38    // Create a group with attributes
39    let group_path = "/group";
40    let mut group = zarrs::group::GroupBuilder::new().build(store.clone(), group_path)?;
41    group
42        .attributes_mut()
43        .insert("foo".into(), serde_json::Value::String("bar".into()));
44    group.async_store_metadata().await?;
45
46    println!(
47        "The group metadata is:\n{}\n",
48        group.metadata().to_string_pretty()
49    );
50
51    // Create an array
52    let array_path = "/group/array";
53    let array = zarrs::array::ArrayBuilder::new(
54        vec![8, 8], // array shape
55        vec![4, 4], // regular chunk shape
56        data_type::float32(),
57        ZARR_NAN_F32,
58    )
59    // .bytes_to_bytes_codecs(vec![]) // uncompressed
60    .dimension_names(["y", "x"].into())
61    // .storage_transformers(vec![].into())
62    .build_arc(store.clone(), array_path)?;
63
64    // Write array metadata to store
65    array.async_store_metadata().await?;
66
67    println!(
68        "The array metadata is:\n{}\n",
69        array.metadata().to_string_pretty()
70    );
71
72    // Write some chunks
73    let store_chunk = |i: u64| {
74        let array = array.clone();
75        async move {
76            let chunk_indices: Vec<u64> = vec![0, i];
77            let chunk_subset = array.chunk_grid().subset(&chunk_indices)?.ok_or_else(|| {
78                zarrs::array::ArrayError::InvalidChunkGridIndicesError(chunk_indices.to_vec())
79            })?;
80            array
81                .async_store_chunk(
82                    &chunk_indices,
83                    vec![i as f32 * 0.1; chunk_subset.num_elements() as usize],
84                )
85                .await
86        }
87    };
88    futures::stream::iter(0..2)
89        .map(Ok)
90        .try_for_each_concurrent(None, store_chunk)
91        .await?;
92
93    let subset_all = array.subset_all();
94    let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
95    println!("async_store_chunk [0, 0] and [0, 1]:\n{data_all:+4.1}\n");
96
97    // Store multiple chunks
98    array
99        .async_store_chunks(
100            &[1..2, 0..2],
101            &[
102                //
103                1.0f32, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
104                //
105                1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1, 1.0, 1.0, 1.0, 1.0, 1.1, 1.1, 1.1, 1.1,
106            ],
107        )
108        .await?;
109    let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
110    println!("async_store_chunks [1..2, 0..2]:\n{data_all:+4.1}\n");
111
112    // Write a subset spanning multiple chunks, including updating chunks already written
113    array
114        .async_store_array_subset(
115            &[3..6, 3..6],
116            &[-3.3, -3.4, -3.5, -4.3, -4.4, -4.5, -5.3, -5.4, -5.5],
117        )
118        .await?;
119    let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
120    println!("async_store_array_subset [3..6, 3..6]:\n{data_all:+4.1}\n");
121
122    // Store array subset
123    array
124        .async_store_array_subset(
125            &[0..8, 6..7],
126            &[-0.6f32, -1.6, -2.6, -3.6, -4.6, -5.6, -6.6, -7.6],
127        )
128        .await?;
129    let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
130    println!("async_store_array_subset [0..8, 6..7]:\n{data_all:+4.1}\n");
131
132    // Store chunk subset
133    array
134        .async_store_chunk_subset(
135            // chunk indices
136            &[1, 1],
137            // subset within chunk
138            &[3..4, 0..4],
139            &[-7.4f32, -7.5, -7.6, -7.7],
140        )
141        .await?;
142    let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
143    println!("async_store_chunk_subset [3..4, 0..4] of chunk [1, 1]:\n{data_all:+4.1}\n");
144
145    // Erase a chunk
146    array.async_erase_chunk(&[0, 0]).await?;
147    let data_all: ArrayD<f32> = array.async_retrieve_array_subset(&subset_all).await?;
148    println!("async_erase_chunk [0, 0]:\n{data_all:+4.1}\n");
149
150    // Read a chunk
151    let chunk_indices = vec![0, 1];
152    let data_chunk: ArrayD<f32> = array.async_retrieve_chunk(&chunk_indices).await?;
153    println!("async_retrieve_chunk [0, 1]:\n{data_chunk:+4.1}\n");
154
155    // Read chunks
156    let chunks = ArraySubset::new_with_ranges(&[0..2, 1..2]);
157    let data_chunks: ArrayD<f32> = array.async_retrieve_chunks(&chunks).await?;
158    println!("async_retrieve_chunks [0..2, 1..2]:\n{data_chunks:+4.1}\n");
159
160    // Retrieve an array subset
161    let subset = ArraySubset::new_with_ranges(&[2..6, 3..5]); // the center 4x2 region
162    let data_subset: ArrayD<f32> = array.async_retrieve_array_subset(&subset).await?;
163    println!("async_retrieve_array_subset [2..6, 3..5]:\n{data_subset:+4.1}\n");
164
165    // Show the hierarchy
166    let node = Node::async_open(store, "/").await.unwrap();
167    let tree = node.hierarchy_tree();
168    println!("hierarchy_tree:\n{}", tree);
169
170    Ok(())
171}

Trait Implementations§

Source§

impl Debug for ArrayBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.