graphrecords_python/graphrecord/
overview.rs1use std::collections::HashMap;
2
3use crate::graphrecord::{
4 attribute::PyGraphRecordAttribute,
5 datatype::PyDataType,
6 schema::PyAttributeType,
7 traits::{DeepFrom, DeepInto},
8 value::PyGraphRecordValue,
9};
10use graphrecords_core::graphrecord::overview::{
11 AttributeOverview, AttributeOverviewData, EdgeGroupOverview, GroupOverview, NodeGroupOverview,
12 Overview,
13};
14use pyo3::{prelude::*, types::PyDict};
15
16#[pyclass(frozen)]
17#[repr(transparent)]
18#[derive(Debug, Clone)]
19pub struct PyAttributeOverview(AttributeOverview);
20
21impl From<AttributeOverview> for PyAttributeOverview {
22 fn from(value: AttributeOverview) -> Self {
23 Self(value)
24 }
25}
26
27impl From<PyAttributeOverview> for AttributeOverview {
28 fn from(value: PyAttributeOverview) -> Self {
29 value.0
30 }
31}
32
33impl DeepFrom<AttributeOverview> for PyAttributeOverview {
34 fn deep_from(value: AttributeOverview) -> Self {
35 value.into()
36 }
37}
38
39impl DeepFrom<PyAttributeOverview> for AttributeOverview {
40 fn deep_from(value: PyAttributeOverview) -> Self {
41 value.into()
42 }
43}
44
45impl AsRef<AttributeOverview> for PyAttributeOverview {
46 fn as_ref(&self) -> &AttributeOverview {
47 &self.0
48 }
49}
50
51#[pymethods]
52impl PyAttributeOverview {
53 #[getter]
54 pub fn data_type(&self) -> PyDataType {
55 self.0.data_type.clone().into()
56 }
57
58 #[getter]
59 #[allow(clippy::missing_panics_doc)]
60 pub fn data(&self, py: Python<'_>) -> Py<PyAny> {
61 let dict = PyDict::new(py);
62
63 match &self.0.data {
64 AttributeOverviewData::Categorical { distinct_values } => {
65 let distinct_values: Vec<PyGraphRecordValue> = distinct_values.clone().deep_into();
66
67 dict.set_item("distinct_values", distinct_values)
68 .expect("Setting item must succeed");
69 dict.set_item("attribute_type", PyAttributeType::Categorical)
70 .expect("Setting item must succeed");
71
72 dict.into_pyobject(py)
73 .expect("Conversion must succeed")
74 .into()
75 }
76 AttributeOverviewData::Continuous { min, mean, max } => {
77 dict.set_item("min", PyGraphRecordValue::from(min.clone()))
78 .expect("Setting item must succeed");
79 dict.set_item("mean", PyGraphRecordValue::from(mean.clone()))
80 .expect("Setting item must succeed");
81 dict.set_item("max", PyGraphRecordValue::from(max.clone()))
82 .expect("Setting item must succeed");
83 dict.set_item("attribute_type", PyAttributeType::Continuous)
84 .expect("Setting item must succeed");
85
86 dict.into()
87 }
88 AttributeOverviewData::Temporal { min, max } => {
89 dict.set_item("min", PyGraphRecordValue::from(min.clone()))
90 .expect("Setting item must succeed");
91 dict.set_item("max", PyGraphRecordValue::from(max.clone()))
92 .expect("Setting item must succeed");
93 dict.set_item("attribute_type", PyAttributeType::Temporal)
94 .expect("Setting item must succeed");
95
96 dict.into()
97 }
98 AttributeOverviewData::Unstructured { distinct_count } => {
99 dict.set_item("distinct_count", *distinct_count)
100 .expect("Setting item must succeed");
101 dict.set_item("attribute_type", PyAttributeType::Unstructured)
102 .expect("Setting item must succeed");
103
104 dict.into()
105 }
106 }
107 }
108}
109
110#[pyclass(frozen)]
111#[repr(transparent)]
112#[derive(Debug, Clone)]
113pub struct PyNodeGroupOverview(NodeGroupOverview);
114
115impl From<NodeGroupOverview> for PyNodeGroupOverview {
116 fn from(value: NodeGroupOverview) -> Self {
117 Self(value)
118 }
119}
120
121impl From<PyNodeGroupOverview> for NodeGroupOverview {
122 fn from(value: PyNodeGroupOverview) -> Self {
123 value.0
124 }
125}
126
127impl DeepFrom<NodeGroupOverview> for PyNodeGroupOverview {
128 fn deep_from(value: NodeGroupOverview) -> Self {
129 value.into()
130 }
131}
132
133impl DeepFrom<PyNodeGroupOverview> for NodeGroupOverview {
134 fn deep_from(value: PyNodeGroupOverview) -> Self {
135 value.into()
136 }
137}
138
139impl AsRef<NodeGroupOverview> for PyNodeGroupOverview {
140 fn as_ref(&self) -> &NodeGroupOverview {
141 &self.0
142 }
143}
144
145#[pymethods]
146impl PyNodeGroupOverview {
147 #[getter]
148 pub const fn count(&self) -> usize {
149 self.0.count
150 }
151
152 #[getter]
153 pub fn attributes(&self) -> HashMap<PyGraphRecordAttribute, PyAttributeOverview> {
154 self.0.attributes.clone().deep_into()
155 }
156
157 pub fn __repr__(&self) -> PyResult<String> {
158 Ok(format!("{}", self.0))
159 }
160}
161
162#[pyclass(frozen)]
163#[repr(transparent)]
164#[derive(Debug, Clone)]
165pub struct PyEdgeGroupOverview(EdgeGroupOverview);
166
167impl From<EdgeGroupOverview> for PyEdgeGroupOverview {
168 fn from(value: EdgeGroupOverview) -> Self {
169 Self(value)
170 }
171}
172
173impl From<PyEdgeGroupOverview> for EdgeGroupOverview {
174 fn from(value: PyEdgeGroupOverview) -> Self {
175 value.0
176 }
177}
178
179impl DeepFrom<EdgeGroupOverview> for PyEdgeGroupOverview {
180 fn deep_from(value: EdgeGroupOverview) -> Self {
181 value.into()
182 }
183}
184
185impl DeepFrom<PyEdgeGroupOverview> for EdgeGroupOverview {
186 fn deep_from(value: PyEdgeGroupOverview) -> Self {
187 value.into()
188 }
189}
190
191impl AsRef<EdgeGroupOverview> for PyEdgeGroupOverview {
192 fn as_ref(&self) -> &EdgeGroupOverview {
193 &self.0
194 }
195}
196
197#[pymethods]
198impl PyEdgeGroupOverview {
199 #[getter]
200 pub const fn count(&self) -> usize {
201 self.0.count
202 }
203
204 #[getter]
205 pub fn attributes(&self) -> HashMap<PyGraphRecordAttribute, PyAttributeOverview> {
206 self.0
207 .attributes
208 .iter()
209 .map(|(k, v)| (k.clone().into(), v.clone().into()))
210 .collect()
211 }
212
213 pub fn __repr__(&self) -> PyResult<String> {
214 Ok(format!("{}", self.0))
215 }
216}
217
218#[pyclass(frozen)]
219#[repr(transparent)]
220#[derive(Debug, Clone)]
221pub struct PyGroupOverview(GroupOverview);
222
223impl From<GroupOverview> for PyGroupOverview {
224 fn from(value: GroupOverview) -> Self {
225 Self(value)
226 }
227}
228
229impl From<PyGroupOverview> for GroupOverview {
230 fn from(value: PyGroupOverview) -> Self {
231 value.0
232 }
233}
234
235impl DeepFrom<GroupOverview> for PyGroupOverview {
236 fn deep_from(value: GroupOverview) -> Self {
237 value.into()
238 }
239}
240
241impl DeepFrom<PyGroupOverview> for GroupOverview {
242 fn deep_from(value: PyGroupOverview) -> Self {
243 value.into()
244 }
245}
246
247impl AsRef<GroupOverview> for PyGroupOverview {
248 fn as_ref(&self) -> &GroupOverview {
249 &self.0
250 }
251}
252
253#[pymethods]
254impl PyGroupOverview {
255 #[getter]
256 pub fn node_overview(&self) -> PyNodeGroupOverview {
257 self.0.node_overview.clone().into()
258 }
259
260 #[getter]
261 pub fn edge_overview(&self) -> PyEdgeGroupOverview {
262 self.0.edge_overview.clone().into()
263 }
264
265 pub fn __repr__(&self) -> PyResult<String> {
266 Ok(format!("{}", self.0))
267 }
268}
269
270#[pyclass(frozen)]
271#[repr(transparent)]
272#[derive(Debug, Clone)]
273pub struct PyOverview(Overview);
274
275impl From<Overview> for PyOverview {
276 fn from(value: Overview) -> Self {
277 Self(value)
278 }
279}
280
281impl From<PyOverview> for Overview {
282 fn from(value: PyOverview) -> Self {
283 value.0
284 }
285}
286
287impl AsRef<Overview> for PyOverview {
288 fn as_ref(&self) -> &Overview {
289 &self.0
290 }
291}
292
293#[pymethods]
294impl PyOverview {
295 #[getter]
296 pub fn ungrouped_overview(&self) -> PyGroupOverview {
297 self.0.ungrouped_overview.clone().into()
298 }
299
300 #[getter]
301 pub fn grouped_overviews(&self) -> HashMap<PyGraphRecordAttribute, PyGroupOverview> {
302 self.0.grouped_overviews.clone().deep_into()
303 }
304
305 pub fn __repr__(&self) -> PyResult<String> {
306 Ok(format!("{}", self.0))
307 }
308}