1use std::{
2 collections::HashMap,
3 fmt,
4 ops::{Deref, DerefMut},
5};
6
7use anndata::{
8 backend::DataType,
9 container::{Axis, Dim},
10 data::{DataFrameIndex, DynArray, DynCscMatrix, DynCsrMatrix, Element, SelectInfoElem, Shape},
11 ArrayData, Data, HasShape, Selectable,
12};
13use anyhow::bail;
14
15use ndarray::Array2;
16use polars::{
17 frame::DataFrame,
18 prelude::{Column, IdxCa, NamedFrom},
19 series::Series,
20};
21
22use crate::base::RwSlot;
23use crate::{base::DeepClone, utils::subset_dyn_csc_matrix, utils::subset_dyn_csr_matrix};
24
25impl DeepClone for ArrayData {
26 fn deep_clone(&self) -> Self {
27 self.clone()
28 }
29}
30
31pub struct IMArrayElement(pub RwSlot<ArrayData>);
32
33impl IMArrayElement {
34 pub fn new(data: ArrayData) -> Self {
35 IMArrayElement(RwSlot::new(data))
36 }
37
38 pub fn get_type(&self) -> anyhow::Result<DataType> {
39 Ok(self.0.read_inner().data_type())
40 }
41
42 pub fn get_shape(&self) -> anyhow::Result<Shape> {
43 Ok(self.0.read_inner().shape())
44 }
45
46 pub fn get_data(&self) -> anyhow::Result<ArrayData> {
47 Ok(self.0.read_inner().clone())
48 }
49
50 pub fn set_data(&self, data: ArrayData) -> anyhow::Result<()> {
51 let mut write_guard = self.0.lock_write();
52 let d = write_guard.deref_mut();
53 *d = Some(data);
54 Ok(())
55 }
56
57 pub fn subset_inplace(&self, s: &[&SelectInfoElem]) -> anyhow::Result<()> {
58 let mut write_guard = self.0.write_inner();
59 let d = write_guard.deref_mut();
60
61 let placeholder = ArrayData::Array(DynArray::from(Array2::<f64>::zeros((0, 0))));
63 let data = std::mem::replace(d, placeholder);
64
65 let result = match data {
67 ArrayData::Array(arr) => Ok(ArrayData::Array(arr).select(s)),
68 ArrayData::DataFrame(df) => Ok(ArrayData::DataFrame(df).select(s)),
69 ArrayData::CsrNonCanonical(csr) => Ok(ArrayData::CsrNonCanonical(csr).select(s)),
70 ArrayData::CsrMatrix(dyn_csr) => {
71 subset_dyn_csr_matrix(dyn_csr, s).map(ArrayData::CsrMatrix)
72 }
73 ArrayData::CscMatrix(dyn_csc) => {
74 subset_dyn_csc_matrix(dyn_csc, s).map(ArrayData::CscMatrix)
75 }
76 };
77
78 match result {
79 Ok(processed) => {
80 *d = processed;
81 Ok(())
82 }
83 Err(e) => {
84 Err(e)
85 }
86 }
87 }
88
89 pub fn convert_matrix_format(&self) -> anyhow::Result<()> {
90 let mut write_guard = self.0.write_inner();
91 let d = write_guard.deref_mut();
92
93 let ddata: Array2<f64> = Array2::zeros((0, 0));
95 let placeholder = ArrayData::Array(DynArray::from(ddata));
96
97 let matrix_data = std::mem::replace(d, placeholder);
99
100 let converted = match matrix_data {
101 ArrayData::CsrMatrix(dyn_csr_matrix) => {
102 let csc = match dyn_csr_matrix {
103 DynCsrMatrix::F64(m) => DynCscMatrix::F64(m.transpose_as_csc()),
104 DynCsrMatrix::F32(m) => DynCscMatrix::F32(m.transpose_as_csc()),
105 DynCsrMatrix::I64(m) => DynCscMatrix::I64(m.transpose_as_csc()),
106 DynCsrMatrix::I32(m) => DynCscMatrix::I32(m.transpose_as_csc()),
107 DynCsrMatrix::I16(m) => DynCscMatrix::I16(m.transpose_as_csc()),
108 DynCsrMatrix::I8(m) => DynCscMatrix::I8(m.transpose_as_csc()),
109 DynCsrMatrix::U64(m) => DynCscMatrix::U64(m.transpose_as_csc()),
110 DynCsrMatrix::U32(m) => DynCscMatrix::U32(m.transpose_as_csc()),
111 DynCsrMatrix::U16(m) => DynCscMatrix::U16(m.transpose_as_csc()),
112 DynCsrMatrix::U8(m) => DynCscMatrix::U8(m.transpose_as_csc()),
113 DynCsrMatrix::Bool(m) => DynCscMatrix::Bool(m.transpose_as_csc()),
114 DynCsrMatrix::String(m) => DynCscMatrix::String(m.transpose_as_csc()),
115 };
116 ArrayData::CscMatrix(csc)
117 }
118 ArrayData::CscMatrix(dyn_csc_matrix) => {
119 let csr = match dyn_csc_matrix {
120 DynCscMatrix::F64(m) => DynCsrMatrix::F64(m.transpose_as_csr()),
121 DynCscMatrix::F32(m) => DynCsrMatrix::F32(m.transpose_as_csr()),
122 DynCscMatrix::I64(m) => DynCsrMatrix::I64(m.transpose_as_csr()),
123 DynCscMatrix::I32(m) => DynCsrMatrix::I32(m.transpose_as_csr()),
124 DynCscMatrix::I16(m) => DynCsrMatrix::I16(m.transpose_as_csr()),
125 DynCscMatrix::I8(m) => DynCsrMatrix::I8(m.transpose_as_csr()),
126 DynCscMatrix::U64(m) => DynCsrMatrix::U64(m.transpose_as_csr()),
127 DynCscMatrix::U32(m) => DynCsrMatrix::U32(m.transpose_as_csr()),
128 DynCscMatrix::U16(m) => DynCsrMatrix::U16(m.transpose_as_csr()),
129 DynCscMatrix::U8(m) => DynCsrMatrix::U8(m.transpose_as_csr()),
130 DynCscMatrix::Bool(m) => DynCsrMatrix::Bool(m.transpose_as_csr()),
131 DynCscMatrix::String(m) => DynCsrMatrix::String(m.transpose_as_csr()),
132 };
133 ArrayData::CsrMatrix(csr)
134 }
135 _ => {
136 *d = matrix_data;
138 bail!("This datatype is not supported, only CSC and CSR matrices are supported.")
139 }
140 };
141
142 *d = converted;
143 Ok(())
144 }
145
146 pub fn subset(&self, s: &[&SelectInfoElem]) -> anyhow::Result<Self> {
147 let read_guard = self.0.read_inner();
148 let d = read_guard.deref();
149
150 Ok(IMArrayElement::new(d.select(s)))
152 }
153
154 pub fn deep_clone_content(&self) -> anyhow::Result<ArrayData> {
155 Ok(self.0.read_inner().clone())
156 }
157}
158
159impl DeepClone for IMArrayElement {
160 fn deep_clone(&self) -> Self {
161 IMArrayElement(self.0.deep_clone())
162 }
163}
164
165impl Clone for IMArrayElement {
166 fn clone(&self) -> Self {
167 IMArrayElement(self.0.clone())
168 }
169}
170
171pub struct IMDataFrameElement(RwSlot<InnerIMDataFrame>);
172
173pub struct InnerIMDataFrame {
174 df: DataFrame,
175 pub index: DataFrameIndex,
176}
177
178impl DeepClone for InnerIMDataFrame {
179 fn deep_clone(&self) -> Self {
180 self.clone()
181 }
182}
183
184impl Clone for InnerIMDataFrame {
185 fn clone(&self) -> Self {
186 InnerIMDataFrame {
187 df: self.df.clone(),
188 index: self.index.clone(),
189 }
190 }
191}
192
193impl Clone for IMDataFrameElement {
194 fn clone(&self) -> Self {
196 IMDataFrameElement(self.0.clone())
197 }
198}
199
200impl IMDataFrameElement {
201 pub fn new(df: DataFrame, index: DataFrameIndex) -> Self {
202 if df.height() == 0 {
203 let tmp_df =
204 DataFrame::new(vec![Column::new("index".into(), &index.clone().into_vec())])
205 .unwrap();
206 return IMDataFrameElement(RwSlot::new(InnerIMDataFrame { df: tmp_df, index }));
207 }
208 if df.height() != index.len() {
209 panic!("Length of index does not match length of DataFrame");
210 }
211 IMDataFrameElement(RwSlot::new(InnerIMDataFrame { df, index }))
212 }
213
214 pub fn get_data(&self) -> DataFrame {
215 self.0.read_inner().df.clone()
216 }
217
218 pub fn get_index(&self) -> DataFrameIndex {
219 self.0.read_inner().index.clone()
220 }
221
222 pub fn set_both(&self, df: DataFrame, index: DataFrameIndex) -> anyhow::Result<()> {
223 let mut write_guard = self.0.lock_write();
224 let d = write_guard.as_mut();
225 match d {
226 Some(data) => {
227 if index.len() != df.height() {
228 return Err(anyhow::anyhow!(
229 "Length of index does not match length of DataFrame"
230 ));
231 }
232
233 data.df = df;
234 data.index = index;
235 Ok(())
236 }
237 None => Err(anyhow::anyhow!("DataFrame is not initialized")),
238 }
239 }
240
241 pub fn set_data(&self, df: DataFrame) -> anyhow::Result<()> {
242 let mut write_guard = self.0.lock_write();
243 let d = write_guard.as_mut();
244 match d {
245 Some(data) => {
246 if data.index.len() != df.height() || data.df.height() != df.height() {
247 return Err(anyhow::anyhow!(
248 "Length of index does not match length of DataFrame"
249 ));
250 }
251 data.df = df;
252 Ok(())
253 }
254 None => Err(anyhow::anyhow!("DataFrame is not initialized")),
255 }
256 }
257
258 pub fn set_index(&self, index: DataFrameIndex) -> anyhow::Result<()> {
259 let mut write_guard = self.0.lock_write();
260 let d = write_guard.as_mut();
261 match d {
262 Some(data) => {
263 if data.df.height() != index.len() || data.index.len() != index.len() {
264 return Err(anyhow::anyhow!(
265 "Length of index does not match length of DataFrame"
266 ));
267 }
268
269 data.index = index;
270 Ok(())
271 }
272 None => Err(anyhow::anyhow!("DataFrame is not initialized")),
273 }
274 }
275
276 pub fn attach_column_to_df(&self, column: Series) -> anyhow::Result<()> {
277 let mut write_guard = self.0.lock_write();
278 let d = write_guard.as_mut();
279 match d {
280 Some(data) => {
281 if data.df.height() != column.len() {
282 return Err(anyhow::anyhow!(
283 "Length of column does not match length of DataFrame"
284 ));
285 }
286 data.df.with_column(column)?;
287 Ok(())
288 }
289 None => Err(anyhow::anyhow!("DataFrame is not initialized")),
290 }
291 }
292
293 pub fn remove_column_from_df(&self, column_name: &str) -> anyhow::Result<()> {
294 let mut write_guard = self.0.lock_write();
295 let d = write_guard.as_mut();
296 match d {
297 Some(data) => {
298 let _ = data.df.drop_in_place(column_name)?;
299 Ok(())
300 }
301 None => Err(anyhow::anyhow!("DataFrame is not initialized")),
302 }
303 }
304
305 pub fn get_column_from_df(&self, column_name: &str) -> anyhow::Result<Column> {
306 let read_guard = self.0.lock_read();
307 let d = read_guard.as_ref();
308 match d {
309 Some(data) => match data.df.column(column_name) {
310 Ok(column) => Ok(column.clone()),
311 Err(e) => Err(anyhow::anyhow!("Column not found: {}", e)),
312 },
313 None => Err(anyhow::anyhow!("DataFrame is not initialized")),
314 }
315 }
316
317 pub fn set_column_in_df(&self, column_name: &str, column: Series) -> anyhow::Result<()> {
318 let mut write_guard = self.0.lock_write();
319 let d = write_guard.as_mut();
320 match d {
321 Some(data) => {
322 data.df.replace(column_name, column)?;
323 Ok(())
324 }
325 None => Err(anyhow::anyhow!("DataFrame is not initialized")),
326 }
327 }
328
329 pub fn subset_inplace(&self, s: &SelectInfoElem) -> anyhow::Result<()> {
330 let read_guard = self.0.lock_read();
331 let d = read_guard.as_ref().unwrap();
332 let indices = crate::utils::select_info_elem_to_indices(s, d.index.len())?;
333 let indices_u32: Vec<u32> = indices.iter().map(|&i| i as u32).collect();
334 let idx = IdxCa::new("idx".into(), &indices_u32);
335 let ind = d.index.clone().into_vec();
336 let ind_subset: Vec<String> = indices.iter().map(|&i| ind[i].clone()).collect();
337 let df_subset = d.df.take(&idx)?;
338 drop(read_guard);
339 self.set_both(df_subset, DataFrameIndex::from(ind_subset))
340 }
341
342 pub fn subset(&self, s: &SelectInfoElem) -> anyhow::Result<Self> {
343 let read_guard = self.0.lock_read();
344 let d = read_guard.as_ref().unwrap();
345 let indices = crate::utils::select_info_elem_to_indices(s, d.index.len())?;
346 let indices_u32: Vec<u32> = indices.iter().map(|&i| i as u32).collect();
347 let idx = IdxCa::new("idx".into(), &indices_u32);
348 let ind = d.index.clone().into_vec();
349 let ind_subset: Vec<String> = indices.iter().map(|&i| ind[i].clone()).collect();
350 let df_subset = d.df.take(&idx)?;
351 Ok(Self::new(df_subset, DataFrameIndex::from(ind_subset)))
352 }
353}
354
355impl DeepClone for IMDataFrameElement {
356 fn deep_clone(&self) -> Self {
357 IMDataFrameElement(self.0.deep_clone())
358 }
359}
360
361pub struct IMAxisArrays(pub RwSlot<InnerIMAxisArray>);
362
363impl Clone for IMAxisArrays {
364 fn clone(&self) -> Self {
365 IMAxisArrays(self.0.clone())
366 }
367}
368
369impl DeepClone for IMAxisArrays {
370 fn deep_clone(&self) -> Self {
371 IMAxisArrays(self.0.deep_clone())
372 }
373}
374
375pub struct InnerIMAxisArray {
376 pub axis: Axis,
377 pub(crate) dim1: Dim,
378 pub(crate) dim2: Option<Dim>,
379 data: HashMap<String, IMArrayElement>,
380}
381
382impl DeepClone for InnerIMAxisArray {
383 fn deep_clone(&self) -> Self {
384 InnerIMAxisArray {
385 axis: self.axis,
386 dim1: self.dim1.clone(),
387 dim2: self.dim2.clone(),
388 data: self
389 .data
390 .iter()
391 .map(|(k, v)| (k.clone(), v.deep_clone()))
392 .collect(),
393 }
394 }
395}
396
397impl Clone for InnerIMAxisArray {
398 fn clone(&self) -> Self {
399 InnerIMAxisArray {
400 axis: self.axis,
401 dim1: self.dim1.clone(),
402 dim2: self.dim2.clone(),
403 data: self.data.clone(),
404 }
405 }
406}
407
408impl fmt::Display for IMAxisArrays {
409 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
410 let read_guard = self.0.read_inner();
411
412 writeln!(f, "IMAxisArrays {{")?;
413 writeln!(f, " Axis: {:?}", read_guard.axis)?;
414 writeln!(f, " Dim1: {}", read_guard.dim1)?;
415 if let Some(dim2) = &read_guard.dim2 {
416 writeln!(f, " Dim2: {}", dim2)?;
417 }
418 writeln!(f, " Arrays: {{")?;
419 for (key, value) in &read_guard.data {
420 let shape = value.get_shape().map_err(|_| fmt::Error)?;
421 writeln!(f, " {}: {:?}", key, shape)?;
422 }
423 writeln!(f, " }}")?;
424 write!(f, "}}")
425 }
426}
427
428impl IMAxisArrays {
429 pub fn new(axis: Axis, dim1: Dim, dim2: Option<Dim>) -> Self {
431 let inner = InnerIMAxisArray {
432 axis,
433 dim1,
434 dim2,
435 data: HashMap::new(),
436 };
437 IMAxisArrays(RwSlot::new(inner))
438 }
439
440 pub fn new_from(
441 axis: Axis,
442 dim1: Dim,
443 dim2: Option<Dim>,
444 data: HashMap<String, IMArrayElement>,
445 ) -> Self {
446 let inner = InnerIMAxisArray {
447 axis,
448 dim1,
449 dim2,
450 data,
451 };
452 IMAxisArrays(RwSlot::new(inner))
453 }
454
455 pub fn add_array(&self, key: String, element: IMArrayElement) -> anyhow::Result<()> {
456 let mut write_guard = self.0.write_inner();
457 let imarray = write_guard.deref_mut();
458 if imarray.data.contains_key(&key) {
460 return Err(anyhow::anyhow!("Key already exists"));
461 }
462
463 let shape = element.get_shape()?;
465 let dim1 = imarray.dim1.get();
466 let dim2 = imarray.dim2.clone().unwrap_or(Dim::new(0)).get();
467
468 match imarray.axis {
470 Axis::Row => {
471 if shape[0] != dim1 {
472 return Err(anyhow::anyhow!(
473 "Data shape {:?} does not match expected row dimension {}",
474 shape,
475 dim1
476 ));
477 }
478 }
479 Axis::RowColumn => {
480 if shape[0] != dim1 || shape[1] != dim2 {
481 return Err(anyhow::anyhow!(
482 "Data shape {:?} does not match expected dimensions ({}, {})",
483 shape,
484 dim1,
485 dim2
486 ));
487 }
488 }
489 Axis::Pairwise => {
490 if shape[0] != dim1 || shape[1] != dim1 {
491 return Err(anyhow::anyhow!(
492 "Data shape {:?} does not match expected pairwise dimensions ({}, {})",
493 shape,
494 dim1,
495 dim1
496 ));
497 }
498 }
499 }
500
501 imarray.data.insert(key, element);
503 Ok(())
504 }
505
506 pub fn get_array(&self, key: &str) -> anyhow::Result<IMArrayElement> {
508 let read_guard = self.0.read_inner();
509 read_guard
510 .data
511 .get(key)
512 .map(|element| element.deep_clone())
513 .ok_or_else(|| anyhow::anyhow!("Key not found"))
514 }
515
516 pub fn get_array_shallow(&self, key: &str) -> anyhow::Result<IMArrayElement> {
518 let read_guard = self.0.read_inner();
519 read_guard
520 .data
521 .get(key)
522 .cloned() .ok_or_else(|| anyhow::anyhow!("Key not found"))
524 }
525
526 pub fn remove_array(&self, key: &str) -> anyhow::Result<IMArrayElement> {
528 let mut write_guard = self.0.write_inner();
529 write_guard
530 .data
531 .remove(key)
532 .ok_or_else(|| anyhow::anyhow!("Key not found"))
533 }
534
535 pub fn len(&self) -> usize {
537 let read_guard = self.0.read_inner();
538 read_guard.data.len()
539 }
540
541 pub fn is_empty(&self) -> bool {
543 let read_guard = self.0.read_inner();
544 read_guard.data.is_empty()
545 }
546
547 pub fn keys(&self) -> Vec<String> {
549 let read_guard = self.0.read_inner();
550 read_guard.data.keys().cloned().collect()
551 }
552
553 pub fn axis(&self) -> Axis {
555 let read_guard = self.0.read_inner();
556 read_guard.axis
557 }
558
559 pub fn dimensions(&self) -> (Dim, Option<Dim>) {
561 let read_guard = self.0.read_inner();
562 (read_guard.dim1.clone(), read_guard.dim2.clone())
563 }
564
565 pub fn update_array(&self, key: &str, new_element: IMArrayElement) -> anyhow::Result<()> {
567 let mut write_guard = self.0.write_inner();
568 if let Some(element) = write_guard.data.get_mut(key) {
569 *element = new_element;
570 Ok(())
571 } else {
572 Err(anyhow::anyhow!("Key not found"))
573 }
574 }
575
576 pub fn subset_inplace(&self, s: &[&SelectInfoElem]) -> anyhow::Result<()> {
577 let mut write_guard = self.0.write_inner();
578 let imarray = write_guard.deref_mut();
579 let dim1_indices = crate::utils::select_info_elem_to_indices(s[0], imarray.dim1.get())?;
580 imarray.dim1 = Dim::new(dim1_indices.len());
581
582 if let Some(dim2) = &mut imarray.dim2 {
583 if s.len() < 2 {
584 return Err(anyhow::anyhow!(
585 "Subset operation requires two selection elements"
586 ));
587 }
588 let dim2_indices = crate::utils::select_info_elem_to_indices(s[1], dim2.get())?;
589 *dim2 = Dim::new(dim2_indices.len());
590 }
591
592 for element in imarray.data.values_mut() {
593 element.subset_inplace(s)?;
594 }
595
596 Ok(())
597 }
598
599 pub fn subset(&self, s: &[&SelectInfoElem]) -> anyhow::Result<Self> {
600 let read_guard = self.0.read_inner();
601 let imarray = read_guard.deref();
602 let dim1_indices = crate::utils::select_info_elem_to_indices(s[0], imarray.dim1.get())?;
603 let new_dim1 = Dim::new(dim1_indices.len());
604 let mut new_dim2: Option<Dim> = None;
605 if imarray.dim2.is_some() {
606 if s.len() < 2 {
607 return Err(anyhow::anyhow!(
608 "Subset operation requires two selection elements"
609 ));
610 }
611 let dim2_indices = crate::utils::select_info_elem_to_indices(
612 s[1],
613 imarray.dim2.clone().unwrap().get(),
614 )?;
615 new_dim2 = Some(Dim::new(dim2_indices.len()));
616 }
617 let mut new_data = HashMap::new();
618 for (key, element) in &imarray.data {
619 new_data.insert(key.clone(), element.subset(s)?);
620 }
621
622 Ok(IMAxisArrays::new_from(
623 imarray.axis,
624 new_dim1,
625 new_dim2,
626 new_data,
627 ))
628 }
629
630 pub fn map<F>(&self, f: F) -> anyhow::Result<()>
632 where
633 F: Fn(&mut IMArrayElement) -> anyhow::Result<()>,
634 {
635 let mut write_guard = self.0.write_inner();
636 for element in write_guard.data.values_mut() {
637 f(element)?;
638 }
639 Ok(())
640 }
641}
642
643pub struct IMElement(pub RwSlot<Data>);
644
645impl DeepClone for Data {
646 fn deep_clone(&self) -> Self {
647 self.clone()
648 }
649}
650
651impl DeepClone for IMElement {
652 fn deep_clone(&self) -> Self {
653 IMElement(self.0.deep_clone())
654 }
655}
656
657impl Clone for IMElement {
658 fn clone(&self) -> Self {
659 IMElement(self.0.clone())
660 }
661}
662
663impl IMElement {
664 pub fn new(data: Data) -> Self {
665 IMElement(RwSlot::new(data))
666 }
667
668 pub fn get_data(&self) -> anyhow::Result<Data> {
669 Ok(self.0.read_inner().clone())
670 }
671
672 pub fn set_data(&self, data: Data) -> anyhow::Result<()> {
673 let mut write_guard = self.0.lock_write();
674 let d = write_guard.deref_mut();
675 *d = Some(data);
676 Ok(())
677 }
678}
679
680pub struct IMElementCollection(pub RwSlot<HashMap<String, IMElement>>);
681
682impl DeepClone for IMElementCollection {
683 fn deep_clone(&self) -> Self {
684 let temp_data = self.0.read_inner();
685 let data = temp_data.deref();
686 let mut new_data = HashMap::new();
687 for (key, value) in data.iter() {
688 new_data.insert(key.clone(), value.deep_clone());
689 }
690 IMElementCollection(RwSlot::new(new_data))
691 }
692}
693
694impl Clone for IMElementCollection {
695 fn clone(&self) -> Self {
696 IMElementCollection(self.0.clone())
697 }
698}
699
700impl IMElementCollection {
701 pub fn new_empty() -> Self {
702 IMElementCollection(RwSlot::new(HashMap::new()))
703 }
704
705 pub fn add_data(&self, key: String, element: IMElement) -> anyhow::Result<()> {
706 let mut write_guard = self.0.write_inner();
707 let collection = write_guard.deref_mut();
708 if collection.contains_key(&key) {
709 return Err(anyhow::anyhow!("Key already exists"));
710 }
711 collection.insert(key, element);
712 Ok(())
713 }
714
715 pub fn remove_data(&self, key: &str) -> anyhow::Result<IMElement> {
716 let mut write_guard = self.0.write_inner();
717 write_guard
718 .remove(key)
719 .ok_or_else(|| anyhow::anyhow!("Key not found"))
720 }
721
722 pub fn get_data(&self, key: &str) -> anyhow::Result<IMElement> {
723 let read_guard = self.0.read_inner();
724 read_guard
725 .get(key)
726 .cloned()
727 .ok_or_else(|| anyhow::anyhow!("Key not found"))
728 }
729
730 pub fn get_data_deep(&self, key: &str) -> anyhow::Result<IMElement> {
731 let read_guard = self.0.read_inner();
732 read_guard
733 .get(key)
734 .map(|element| element.deep_clone())
735 .ok_or_else(|| anyhow::anyhow!("Key not found"))
736 }
737
738 pub fn keys(&self) -> anyhow::Result<Vec<String>> {
739 let read_guard = self.0.read_inner();
740 let data = read_guard.deref();
741 let keys = data.keys().map(|k| k.clone()).collect();
742 Ok(keys)
743 }
744}