proper_path_tools/path/
joining.rs

1mod 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
170crate::mod_interface!
171{
172  orphan use join;
173  exposed use PathJoined;
174}