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