Skip to content

Commit 6ff7743

Browse files
committed
refactor: Move Reflection's methods to their own modules
1 parent dac3f69 commit 6ff7743

File tree

3 files changed

+129
-126
lines changed

3 files changed

+129
-126
lines changed

src/data_tree/reflection.rs

Lines changed: 8 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
use super::DataTree;
21
use crate::size::Size;
3-
use rayon::prelude::*;
42
use std::{
53
collections::VecDeque,
64
ffi::OsStr,
75
fmt::{Debug, Display, Error, Formatter},
8-
iter::once,
96
path::PathBuf,
107
};
118

129
#[cfg(feature = "json")]
1310
use serde::{Deserialize, Serialize};
1411

15-
/// Intermediate format used for construction and inspection of [`DataTree`]'s internal content.
12+
/// Intermediate format used for construction and inspection of
13+
/// [`DataTree`](crate::data_tree::DataTree)'s internal content.
1614
///
1715
/// Unlike `Tree` where the fields are all private, the fields of `TreeReflection`
1816
/// are all public to allow construction in tests.
@@ -21,7 +19,8 @@ use serde::{Deserialize, Serialize};
2119
/// * Any `DataTree` can be safely [transmuted](std::mem::transmute) to a valid `Reflection`.
2220
/// * Any `Reflection` can be safely transmuted to a potentially invalid `DataTree`.
2321
/// * To safely convert a `DataTree` into a `Reflection` without the `unsafe` keyword, use
24-
/// [`DataTree::into_reflection`] (it would be slower than using `transmute`).
22+
/// [`DataTree::into_reflection`](crate::data_tree::DataTree::into_reflection)
23+
/// (it would be slower than using `transmute`).
2524
/// * To safely convert a `Reflection` into a valid `DataTree`,
2625
/// use [`par_try_into_tree`](Self::par_try_into_tree).
2726
///
@@ -37,30 +36,8 @@ pub struct Reflection<Name, Data: Size> {
3736
pub children: Vec<Self>,
3837
}
3938

40-
impl<Name, Data: Size> From<DataTree<Name, Data>> for Reflection<Name, Data> {
41-
fn from(source: DataTree<Name, Data>) -> Self {
42-
let DataTree {
43-
name,
44-
data,
45-
children,
46-
} = source;
47-
let children: Vec<_> = children.into_iter().map(Reflection::from).collect();
48-
Reflection {
49-
name,
50-
data,
51-
children,
52-
}
53-
}
54-
}
55-
56-
impl<Name, Data: Size> DataTree<Name, Data> {
57-
/// Create reflection.
58-
pub fn into_reflection(self) -> Reflection<Name, Data> {
59-
self.into()
60-
}
61-
}
62-
63-
/// Error that occurs when an attempt to convert a [`Reflection`] into a [`DataTree`] fails.
39+
/// Error that occurs when an attempt to convert a [`Reflection`] into a
40+
/// [`DataTree`](crate::data_tree::DataTree) fails.
6441
#[derive(Debug, Clone, PartialEq, Eq)]
6542
#[non_exhaustive]
6643
pub enum ConversionError<Name, Data: Size> {
@@ -107,100 +84,5 @@ where
10784
}
10885
}
10986

110-
impl<Name, Data> Reflection<Name, Data>
111-
where
112-
Name: Send,
113-
Data: Size + Send,
114-
{
115-
/// Attempting to convert a [`Reflection`] into a valid [`DataTree`].
116-
pub fn par_try_into_tree(self) -> Result<DataTree<Name, Data>, ConversionError<Name, Data>> {
117-
let Reflection {
118-
name,
119-
data,
120-
children,
121-
} = self;
122-
let children_sum = children.iter().map(|child| child.data).sum();
123-
if data < children_sum {
124-
return Err(ConversionError::ExcessiveChildren {
125-
path: once(name).collect(),
126-
data,
127-
children,
128-
children_sum,
129-
});
130-
}
131-
let children: Result<Vec<_>, _> = children
132-
.into_par_iter()
133-
.map(Self::par_try_into_tree)
134-
.collect();
135-
let children = match children {
136-
Ok(children) => children,
137-
Err(ConversionError::ExcessiveChildren {
138-
mut path,
139-
data,
140-
children,
141-
children_sum,
142-
}) => {
143-
path.push_front(name);
144-
return Err(ConversionError::ExcessiveChildren {
145-
path,
146-
data,
147-
children,
148-
children_sum,
149-
});
150-
}
151-
};
152-
Ok(DataTree {
153-
name,
154-
data,
155-
children,
156-
})
157-
}
158-
}
159-
160-
impl<Name, Data> Reflection<Name, Data>
161-
where
162-
Name: Send,
163-
Data: Size + Send,
164-
{
165-
/// Attempt to transform names and data.
166-
pub fn par_try_map<TargetName, TargetData, Error, Transform>(
167-
self,
168-
transform: Transform,
169-
) -> Result<Reflection<TargetName, TargetData>, Error>
170-
where
171-
TargetName: Send,
172-
TargetData: Size + Send + Sync,
173-
Error: Send,
174-
Transform: Fn(Name, Data) -> Result<(TargetName, TargetData), Error> + Copy + Sync,
175-
{
176-
let Reflection {
177-
name,
178-
data,
179-
children,
180-
} = self;
181-
let children = children
182-
.into_par_iter()
183-
.map(|child| child.par_try_map(transform))
184-
.collect::<Result<Vec<_>, _>>()?;
185-
let (name, data) = transform(name, data)?;
186-
Ok(Reflection {
187-
name,
188-
data,
189-
children,
190-
})
191-
}
192-
193-
/// Attempt to convert all names from `OsString` to `String`.
194-
pub fn par_convert_names_to_utf8(self) -> Result<Reflection<String, Data>, Name>
195-
where
196-
Name: AsRef<OsStr>,
197-
Data: Sync,
198-
{
199-
self.par_try_map(|name, data| {
200-
name.as_ref()
201-
.to_str()
202-
.map(|name| (name.to_string(), data))
203-
.ok_or(name)
204-
})
205-
}
206-
}
87+
mod convert;
88+
mod par_methods;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use super::Reflection;
2+
use crate::{data_tree::DataTree, size::Size};
3+
4+
impl<Name, Data: Size> From<DataTree<Name, Data>> for Reflection<Name, Data> {
5+
fn from(source: DataTree<Name, Data>) -> Self {
6+
let DataTree {
7+
name,
8+
data,
9+
children,
10+
} = source;
11+
let children: Vec<_> = children.into_iter().map(Reflection::from).collect();
12+
Reflection {
13+
name,
14+
data,
15+
children,
16+
}
17+
}
18+
}
19+
20+
impl<Name, Data: Size> DataTree<Name, Data> {
21+
/// Create reflection.
22+
pub fn into_reflection(self) -> Reflection<Name, Data> {
23+
self.into()
24+
}
25+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use super::{ConversionError, Reflection};
2+
use crate::{data_tree::DataTree, size::Size};
3+
use rayon::prelude::*;
4+
use std::{ffi::OsStr, iter::once};
5+
6+
impl<Name, Data> Reflection<Name, Data>
7+
where
8+
Name: Send,
9+
Data: Size + Send,
10+
{
11+
/// Attempting to convert a [`Reflection`] into a valid [`DataTree`].
12+
pub fn par_try_into_tree(self) -> Result<DataTree<Name, Data>, ConversionError<Name, Data>> {
13+
let Reflection {
14+
name,
15+
data,
16+
children,
17+
} = self;
18+
let children_sum = children.iter().map(|child| child.data).sum();
19+
if data < children_sum {
20+
return Err(ConversionError::ExcessiveChildren {
21+
path: once(name).collect(),
22+
data,
23+
children,
24+
children_sum,
25+
});
26+
}
27+
let children: Result<Vec<_>, _> = children
28+
.into_par_iter()
29+
.map(Self::par_try_into_tree)
30+
.collect();
31+
let children = match children {
32+
Ok(children) => children,
33+
Err(ConversionError::ExcessiveChildren {
34+
mut path,
35+
data,
36+
children,
37+
children_sum,
38+
}) => {
39+
path.push_front(name);
40+
return Err(ConversionError::ExcessiveChildren {
41+
path,
42+
data,
43+
children,
44+
children_sum,
45+
});
46+
}
47+
};
48+
Ok(DataTree {
49+
name,
50+
data,
51+
children,
52+
})
53+
}
54+
55+
/// Attempt to transform names and data.
56+
pub fn par_try_map<TargetName, TargetData, Error, Transform>(
57+
self,
58+
transform: Transform,
59+
) -> Result<Reflection<TargetName, TargetData>, Error>
60+
where
61+
TargetName: Send,
62+
TargetData: Size + Send + Sync,
63+
Error: Send,
64+
Transform: Fn(Name, Data) -> Result<(TargetName, TargetData), Error> + Copy + Sync,
65+
{
66+
let Reflection {
67+
name,
68+
data,
69+
children,
70+
} = self;
71+
let children = children
72+
.into_par_iter()
73+
.map(|child| child.par_try_map(transform))
74+
.collect::<Result<Vec<_>, _>>()?;
75+
let (name, data) = transform(name, data)?;
76+
Ok(Reflection {
77+
name,
78+
data,
79+
children,
80+
})
81+
}
82+
83+
/// Attempt to convert all names from `OsString` to `String`.
84+
pub fn par_convert_names_to_utf8(self) -> Result<Reflection<String, Data>, Name>
85+
where
86+
Name: AsRef<OsStr>,
87+
Data: Sync,
88+
{
89+
self.par_try_map(|name, data| {
90+
name.as_ref()
91+
.to_str()
92+
.map(|name| (name.to_string(), data))
93+
.ok_or(name)
94+
})
95+
}
96+
}

0 commit comments

Comments
 (0)