Skip to content

Commit f8e9106

Browse files
committed
path_tools : path::join implemented
1 parent 77379e6 commit f8e9106

File tree

4 files changed

+353
-112
lines changed

4 files changed

+353
-112
lines changed

module/core/proper_path_tools/src/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,6 @@ crate::mod_interface!
10771077
layer native_path;
10781078

10791079
/// Convenient joining.
1080-
layer join;
1080+
layer joining;
10811081

10821082
}

module/core/proper_path_tools/src/path/join.rs

Lines changed: 0 additions & 74 deletions
This file was deleted.
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
mod private
2+
{
3+
use crate::*;
4+
use std::{ io, path::PathBuf };
5+
6+
/// Joins path components into a `PathBuf`.
7+
///
8+
/// This function leverages the `PathJoined` trait to join multiple path components into a single `PathBuf`.
9+
///
10+
/// # Arguments
11+
///
12+
/// * `paths` - A tuple of path components implementing the `PathJoined` trait.
13+
///
14+
/// # Returns
15+
///
16+
/// * `Ok(PathBuf)` - The joined path as a `PathBuf`.
17+
/// * `Err(io::Error)` - An error if any component fails to convert.
18+
pub fn join< Paths : PathJoined >( paths : Paths ) -> Result< PathBuf, io::Error >
19+
{
20+
paths.join_paths()
21+
}
22+
23+
/// A trait for joining path components into a `PathBuf`.
24+
///
25+
/// This trait provides a method to join multiple path components into a single `PathBuf`.
26+
/// It is implemented for tuples of varying lengths, allowing for flexible combinations of path components.
27+
/// Each component must implement the `TryIntoCowPath` trait, enabling conversion into a `Cow<Path>`.
28+
pub trait PathJoined
29+
{
30+
/// Joins the path components into a single `PathBuf`.
31+
///
32+
/// # Returns
33+
///
34+
/// * `Ok(PathBuf)` - The joined path as a `PathBuf`.
35+
/// * `Err(io::Error)` - An error if any component fails to convert.
36+
fn join_paths( self ) -> Result< PathBuf, io::Error >;
37+
}
38+
39+
// Implementation for a tuple of length 1
40+
impl< 'a, T1 > PathJoined for ( T1, )
41+
where
42+
T1 : TryIntoCowPath< 'a >,
43+
{
44+
#[ inline ]
45+
fn join_paths( self ) -> Result< PathBuf, io::Error >
46+
{
47+
let ( p1, ) = self;
48+
let mut result = PathBuf::new();
49+
result.push( p1.try_into_cow_path()?.as_ref() );
50+
Ok( result )
51+
}
52+
}
53+
54+
// Implementation for a tuple of length 2
55+
impl< 'a, T1, T2 > PathJoined for ( T1, T2 )
56+
where
57+
T1 : TryIntoCowPath< 'a >,
58+
T2 : TryIntoCowPath< 'a >,
59+
{
60+
#[ inline ]
61+
fn join_paths( self ) -> Result< PathBuf, io::Error >
62+
{
63+
let ( p1, p2 ) = self;
64+
let mut result = PathBuf::new();
65+
result.push( p1.try_into_cow_path()?.as_ref() );
66+
result.push( p2.try_into_cow_path()?.as_ref() );
67+
Ok( result )
68+
}
69+
}
70+
71+
// Implementation for a tuple of length 3
72+
impl< 'a, T1, T2, T3 > PathJoined for ( T1, T2, T3 )
73+
where
74+
T1 : TryIntoCowPath< 'a >,
75+
T2 : TryIntoCowPath< 'a >,
76+
T3 : TryIntoCowPath< 'a >,
77+
{
78+
#[ inline ]
79+
fn join_paths( self ) -> Result< PathBuf, io::Error >
80+
{
81+
let ( p1, p2, p3 ) = self;
82+
let mut result = PathBuf::new();
83+
result.push( p1.try_into_cow_path()?.as_ref() );
84+
result.push( p2.try_into_cow_path()?.as_ref() );
85+
result.push( p3.try_into_cow_path()?.as_ref() );
86+
Ok( result )
87+
}
88+
}
89+
90+
// Implementation for a tuple of length 4
91+
impl< 'a, T1, T2, T3, T4 > PathJoined for ( T1, T2, T3, T4 )
92+
where
93+
T1 : TryIntoCowPath< 'a >,
94+
T2 : TryIntoCowPath< 'a >,
95+
T3 : TryIntoCowPath< 'a >,
96+
T4 : TryIntoCowPath< 'a >,
97+
{
98+
#[ inline ]
99+
fn join_paths( self ) -> Result< PathBuf, io::Error >
100+
{
101+
let ( p1, p2, p3, p4 ) = self;
102+
let mut result = PathBuf::new();
103+
result.push( p1.try_into_cow_path()?.as_ref() );
104+
result.push( p2.try_into_cow_path()?.as_ref() );
105+
result.push( p3.try_into_cow_path()?.as_ref() );
106+
result.push( p4.try_into_cow_path()?.as_ref() );
107+
Ok( result )
108+
}
109+
}
110+
111+
// Implementation for a tuple of length 5
112+
impl< 'a, T1, T2, T3, T4, T5 > PathJoined for ( T1, T2, T3, T4, T5 )
113+
where
114+
T1 : TryIntoCowPath< 'a >,
115+
T2 : TryIntoCowPath< 'a >,
116+
T3 : TryIntoCowPath< 'a >,
117+
T4 : TryIntoCowPath< 'a >,
118+
T5 : TryIntoCowPath< 'a >,
119+
{
120+
#[ inline ]
121+
fn join_paths( self ) -> Result< PathBuf, io::Error >
122+
{
123+
let ( p1, p2, p3, p4, p5 ) = self;
124+
let mut result = PathBuf::new();
125+
result.push( p1.try_into_cow_path()?.as_ref() );
126+
result.push( p2.try_into_cow_path()?.as_ref() );
127+
result.push( p3.try_into_cow_path()?.as_ref() );
128+
result.push( p4.try_into_cow_path()?.as_ref() );
129+
result.push( p5.try_into_cow_path()?.as_ref() );
130+
Ok( result )
131+
}
132+
}
133+
134+
// Implementation for slices
135+
impl< 'a, T > PathJoined for &'a [ T ]
136+
where
137+
T : TryIntoCowPath< 'a > + Clone,
138+
{
139+
#[ inline ]
140+
fn join_paths( self ) -> Result< PathBuf, io::Error >
141+
{
142+
let mut result = PathBuf::new();
143+
for item in self
144+
{
145+
result.push( item.clone().try_into_cow_path()?.as_ref() );
146+
}
147+
Ok( result )
148+
}
149+
}
150+
151+
// Implementation for arrays
152+
impl< 'a, T, const N : usize > PathJoined for [ T; N ]
153+
where
154+
T : TryIntoCowPath< 'a > + Clone,
155+
{
156+
#[ inline ]
157+
fn join_paths( self ) -> Result< PathBuf, io::Error >
158+
{
159+
let mut result = PathBuf::new();
160+
for item in &self
161+
{
162+
result.push( item.clone().try_into_cow_path()?.as_ref() );
163+
}
164+
Ok( result )
165+
}
166+
}
167+
168+
}
169+
170+
crate::mod_interface!
171+
{
172+
orphan use join;
173+
exposed use PathJoined;
174+
}

0 commit comments

Comments
 (0)