Skip to main content

exarrow_rs/import/
source.rs

1//! File source types for parallel import operations.
2//!
3//! This module provides the `IntoFileSources` trait which allows both single file paths
4//! and collections of file paths to be used with the parallel import functions.
5
6use std::path::{Path, PathBuf};
7
8/// Trait for types that can be converted to a collection of file sources.
9///
10/// This trait enables the parallel import functions to accept both single paths
11/// and collections of paths, providing a flexible API.
12///
13/// # Example
14///
15/// ```rust
16/// use std::path::PathBuf;
17/// use exarrow_rs::import::IntoFileSources;
18///
19/// // Single path
20/// let single = PathBuf::from("/data/file.csv");
21/// let sources: Vec<PathBuf> = single.into_sources();
22/// assert_eq!(sources.len(), 1);
23///
24/// // Multiple paths
25/// let multiple = vec![
26///     PathBuf::from("/data/file1.csv"),
27///     PathBuf::from("/data/file2.csv"),
28/// ];
29/// let sources: Vec<PathBuf> = multiple.into_sources();
30/// assert_eq!(sources.len(), 2);
31/// ```
32pub trait IntoFileSources {
33    /// Convert this type into a vector of file paths.
34    fn into_sources(self) -> Vec<PathBuf>;
35}
36
37impl IntoFileSources for PathBuf {
38    fn into_sources(self) -> Vec<PathBuf> {
39        vec![self]
40    }
41}
42
43impl IntoFileSources for &Path {
44    fn into_sources(self) -> Vec<PathBuf> {
45        vec![self.to_path_buf()]
46    }
47}
48
49impl IntoFileSources for &PathBuf {
50    fn into_sources(self) -> Vec<PathBuf> {
51        vec![self.clone()]
52    }
53}
54
55impl IntoFileSources for Vec<PathBuf> {
56    fn into_sources(self) -> Vec<PathBuf> {
57        self
58    }
59}
60
61impl IntoFileSources for &[PathBuf] {
62    fn into_sources(self) -> Vec<PathBuf> {
63        self.to_vec()
64    }
65}
66
67impl<const N: usize> IntoFileSources for [PathBuf; N] {
68    fn into_sources(self) -> Vec<PathBuf> {
69        self.into_iter().collect()
70    }
71}
72
73impl<const N: usize> IntoFileSources for &[PathBuf; N] {
74    fn into_sources(self) -> Vec<PathBuf> {
75        self.iter().cloned().collect()
76    }
77}
78
79// Also support String and &str for convenience
80impl IntoFileSources for String {
81    fn into_sources(self) -> Vec<PathBuf> {
82        vec![PathBuf::from(self)]
83    }
84}
85
86impl IntoFileSources for &str {
87    fn into_sources(self) -> Vec<PathBuf> {
88        vec![PathBuf::from(self)]
89    }
90}
91
92impl IntoFileSources for Vec<String> {
93    fn into_sources(self) -> Vec<PathBuf> {
94        self.into_iter().map(PathBuf::from).collect()
95    }
96}
97
98impl IntoFileSources for Vec<&str> {
99    fn into_sources(self) -> Vec<PathBuf> {
100        self.into_iter().map(PathBuf::from).collect()
101    }
102}
103
104#[cfg(test)]
105mod tests {
106    use super::*;
107
108    #[test]
109    fn test_pathbuf_into_sources() {
110        let path = PathBuf::from("/data/file.csv");
111        let sources = path.into_sources();
112        assert_eq!(sources.len(), 1);
113        assert_eq!(sources[0], PathBuf::from("/data/file.csv"));
114    }
115
116    #[test]
117    fn test_path_ref_into_sources() {
118        let path = Path::new("/data/file.csv");
119        let sources = path.into_sources();
120        assert_eq!(sources.len(), 1);
121        assert_eq!(sources[0], PathBuf::from("/data/file.csv"));
122    }
123
124    #[test]
125    fn test_pathbuf_ref_into_sources() {
126        let path = PathBuf::from("/data/file.csv");
127        let sources = (&path).into_sources();
128        assert_eq!(sources.len(), 1);
129        assert_eq!(sources[0], PathBuf::from("/data/file.csv"));
130    }
131
132    #[test]
133    fn test_vec_pathbuf_into_sources() {
134        let paths = vec![
135            PathBuf::from("/data/file1.csv"),
136            PathBuf::from("/data/file2.csv"),
137            PathBuf::from("/data/file3.csv"),
138        ];
139        let sources = paths.into_sources();
140        assert_eq!(sources.len(), 3);
141        assert_eq!(sources[0], PathBuf::from("/data/file1.csv"));
142        assert_eq!(sources[1], PathBuf::from("/data/file2.csv"));
143        assert_eq!(sources[2], PathBuf::from("/data/file3.csv"));
144    }
145
146    #[test]
147    fn test_slice_pathbuf_into_sources() {
148        let paths = vec![
149            PathBuf::from("/data/file1.csv"),
150            PathBuf::from("/data/file2.csv"),
151        ];
152        let sources = paths.as_slice().into_sources();
153        assert_eq!(sources.len(), 2);
154    }
155
156    #[test]
157    fn test_array_pathbuf_into_sources() {
158        let paths: [PathBuf; 2] = [
159            PathBuf::from("/data/file1.csv"),
160            PathBuf::from("/data/file2.csv"),
161        ];
162        let sources = paths.into_sources();
163        assert_eq!(sources.len(), 2);
164    }
165
166    #[test]
167    fn test_array_ref_pathbuf_into_sources() {
168        let paths: [PathBuf; 2] = [
169            PathBuf::from("/data/file1.csv"),
170            PathBuf::from("/data/file2.csv"),
171        ];
172        let sources = (&paths).into_sources();
173        assert_eq!(sources.len(), 2);
174    }
175
176    #[test]
177    fn test_string_into_sources() {
178        let path = String::from("/data/file.csv");
179        let sources = path.into_sources();
180        assert_eq!(sources.len(), 1);
181        assert_eq!(sources[0], PathBuf::from("/data/file.csv"));
182    }
183
184    #[test]
185    fn test_str_into_sources() {
186        let sources = "/data/file.csv".into_sources();
187        assert_eq!(sources.len(), 1);
188        assert_eq!(sources[0], PathBuf::from("/data/file.csv"));
189    }
190
191    #[test]
192    fn test_vec_string_into_sources() {
193        let paths = vec![
194            String::from("/data/file1.csv"),
195            String::from("/data/file2.csv"),
196        ];
197        let sources = paths.into_sources();
198        assert_eq!(sources.len(), 2);
199    }
200
201    #[test]
202    fn test_vec_str_into_sources() {
203        let paths = vec!["/data/file1.csv", "/data/file2.csv"];
204        let sources = paths.into_sources();
205        assert_eq!(sources.len(), 2);
206    }
207
208    #[test]
209    fn test_empty_vec_into_sources() {
210        let paths: Vec<PathBuf> = vec![];
211        let sources = paths.into_sources();
212        assert!(sources.is_empty());
213    }
214}