Skip to main content

tree_table/types/
index_cell.rs

1use super::cell_props::CellProps;
2use super::val::Val;
3use crate::Change;
4use crate::EventData;
5use crate::MaxMap;
6use crate::TableCell;
7use alloc::borrow::{Borrow, Cow};
8use alloc::rc::Rc;
9use alloc::string::String;
10use alloc::vec::Vec;
11use core::hash::Hash;
12use core::hash::Hasher;
13
14#[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
15#[cfg_attr(feature = "tsify", tsify(from_wasm_abi))]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17#[derive(Debug, Clone)]
18pub struct IndexCell {
19    pub iid: Rc<str>,
20    pub val: Val,
21    pub vals: MaxMap<TableCell>,
22    pub dim: u64,
23    pub vis: bool,
24    pub par: Rc<str>,
25    pub chn: Vec<Rc<str>>,
26    pub open: bool,
27    pub props: Option<CellProps>,
28}
29
30impl Borrow<str> for IndexCell {
31    fn borrow(&self) -> &str {
32        &self.iid
33    }
34}
35
36impl PartialEq for IndexCell {
37    fn eq(&self, other: &Self) -> bool {
38        self.iid == other.iid
39    }
40}
41
42impl Eq for IndexCell {}
43
44impl Hash for IndexCell {
45    fn hash<H: Hasher>(&self, state: &mut H) {
46        self.iid.hash(state);
47    }
48}
49
50impl IndexCell {
51    pub fn new(val: Val, dim: u64, vis: bool, iid: Rc<str>) -> Self {
52        IndexCell {
53            iid,
54            val,
55            vals: MaxMap::new(),
56            dim,
57            vis,
58            par: Rc::from(""),
59            chn: Vec::new(),
60            open: false,
61            props: None,
62        }
63    }
64
65    #[inline(always)]
66    pub fn event_data_apply_own_iformat(
67        &mut self,
68        row: usize,
69        event_data: &mut EventData,
70        normalize: bool,
71        ignore_fmt_errs: bool,
72    ) -> Result<bool, String> {
73        let Some(fmt) = self
74            .props
75            .as_ref()
76            .and_then(|props| props.data_format.as_ref())
77        else {
78            return Ok(false);
79        };
80
81        match fmt.try_format_val(&self.val, normalize) {
82            Ok(Cow::Owned(new_val)) => {
83                if new_val != self.val {
84                    let change = self.record_set_val(new_val);
85                    event_data.changes.push(Change::IndexCell { row, change });
86                    Ok(true)
87                } else {
88                    Ok(false)
89                }
90            }
91            Ok(Cow::Borrowed(_)) => Ok(false), // same-type + !normalize = no-op
92            Err(e) => {
93                if ignore_fmt_errs {
94                    Ok(false)
95                } else {
96                    Err(e)
97                }
98            }
99        }
100    }
101
102    #[inline(always)]
103    pub fn event_data_apply_own_tformat(
104        &mut self,
105        row: usize,
106        col: usize,
107        empty_val: &Val,
108        event_data: &mut EventData,
109        normalize: bool,
110        ignore_fmt_errs: bool,
111    ) -> Result<bool, String> {
112        let Some(fmt) = self
113            .vals
114            .get(&col)
115            .and_then(|tc| tc.props.as_ref())
116            .and_then(|props| props.data_format.as_ref())
117        else {
118            return Ok(false);
119        };
120
121        match fmt.try_format_val(&self.val, normalize) {
122            Ok(Cow::Owned(new_val)) => {
123                if new_val != self.val {
124                    let change = self.record_set_table_cell_val(col, new_val, empty_val.clone());
125                    event_data.changes.push(Change::IndexCell { row, change });
126                    Ok(true)
127                } else {
128                    Ok(false)
129                }
130            }
131            Ok(Cow::Borrowed(_)) => Ok(false), // same-type + !normalize = no-op
132            Err(e) => {
133                if ignore_fmt_errs {
134                    Ok(false)
135                } else {
136                    Err(e)
137                }
138            }
139        }
140    }
141}