Skip to content

Commit 4bc2bcc

Browse files
committed
Add more tests for valid URL checking
1 parent 67a2f3f commit 4bc2bcc

File tree

2 files changed

+48
-28
lines changed

2 files changed

+48
-28
lines changed

src/reader/file.rs

+41-26
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,29 @@ use crate::utils::generic_iterator::GenericIterator;
1313
use crate::utils::runtime::tokio_block_on;
1414

1515
/// Implements standard file reading from local FS
16-
pub struct FileReader{
16+
pub struct FileReader {
1717
path: String,
1818
file: File,
1919
}
2020

21-
struct DirectoryIteratorState{
21+
struct DirectoryIteratorState {
2222
objects: Vec<OsString>,
2323
current_object: usize,
2424
_full_path: OsString,
2525
}
2626

2727
impl DirectoryIteratorState {
28-
pub fn new(path: String) -> DirectoryIteratorState{
28+
pub fn new(path: String) -> DirectoryIteratorState {
2929
let path = Path::new(&path);
30-
let objects = if path.is_file(){
30+
let objects = if path.is_file() {
3131
vec![OsString::from(&path)]
3232
} else {
3333
std::fs::read_dir(path).expect("Can not read directory")
34-
.map(|x| {x.unwrap().path().into_os_string()})
34+
.map(|x| { x.unwrap().path().into_os_string() })
3535
.collect()
3636
};
3737
//println!("path {:?} has objects {:?}", path, objects);
38-
DirectoryIteratorState{
38+
DirectoryIteratorState {
3939
objects,
4040
current_object: 0,
4141
_full_path: OsString::from(&path),
@@ -44,12 +44,12 @@ impl DirectoryIteratorState {
4444

4545
#[inline]
4646
#[allow(dead_code)]
47-
pub fn len(&self) -> usize{
47+
pub fn len(&self) -> usize {
4848
self.objects.len()
4949
}
5050

51-
pub fn next_object(&mut self) -> Option<OsString>{
52-
if self.current_object >= self.objects.len(){
51+
pub fn next_object(&mut self) -> Option<OsString> {
52+
if self.current_object >= self.objects.len() {
5353
None
5454
} else {
5555
let result = Some(self.objects[self.current_object].clone());
@@ -64,64 +64,68 @@ struct DirectoryIterator {
6464
state_stack: Vec<DirectoryIteratorState>,
6565
}
6666

67-
impl DirectoryIterator{
68-
pub fn new(url: &str) -> DirectoryIterator{
69-
DirectoryIterator{
67+
impl DirectoryIterator {
68+
pub fn new(url: &str) -> DirectoryIterator {
69+
DirectoryIterator {
7070
_base_directory: url.to_string(),
7171
state_stack: vec![DirectoryIteratorState::new(url.to_string())],
7272
}
7373
}
7474
}
7575

76-
impl GenericIterator<String> for DirectoryIterator{
76+
impl GenericIterator<String> for DirectoryIterator {
7777
fn internal_next(&mut self) -> Option<String> {
78-
if self.state_stack.len() == 0{
78+
if self.state_stack.len() == 0 {
7979
return None;
8080
}
8181
let mut next_object = self.state_stack.last_mut().unwrap().next_object();
8282
//println!("next_object={:?}", next_object);
83-
while next_object.is_none() && self.state_stack.len() > 1{
83+
while next_object.is_none() && self.state_stack.len() > 1 {
8484
self.state_stack.pop();
8585
next_object = self.state_stack.last_mut().unwrap().next_object();
8686
}
87-
if next_object.is_none(){
87+
if next_object.is_none() {
8888
//println!("No more objects through stack");
8989
return None;
9090
}
9191
let path_os_string = next_object.unwrap();
9292
let path_string = path_os_string.to_str().unwrap().to_string();
93-
if Path::new(&path_os_string).is_dir(){
93+
if Path::new(&path_os_string).is_dir() {
9494
self.state_stack.push(DirectoryIteratorState::new(path_string.clone()));
9595
}
9696
Some(path_string)
9797
}
9898
}
9999

100100

101+
#[inline]
102+
fn check_valid_url(url: &str) -> bool {
103+
let re = Regex::new(r"^(/?[\s\w'.-]+)+(/)?$").unwrap();
104+
re.is_match(url)
105+
}
101106

102107
#[async_trait]
103-
impl Reader for FileReader{
108+
impl Reader for FileReader {
104109
fn can_read(url: &str) -> bool where Self: Sized {
105-
let re = Regex::new(r"^(/?[\w.-]+)+(/)?$").unwrap();
106-
if !re.is_match(url){
107-
return false
110+
if !check_valid_url(url) {
111+
return false;
108112
}
109113
let path = Path::new(url);
110-
if !path.is_file() && !path.is_dir(){
114+
if !path.is_file() && !path.is_dir() {
111115
println!("{}:{} No such file or directory", url.bold().red(), "".clear());
112116
return false;
113117
}
114118
true
115119
}
116120
fn new(url: &str) -> Self where Self: Sized {
117-
if !Self::can_read(url){
121+
if !Self::can_read(url) {
118122
//panic!("Can not read url {url}");
119123
}
120124
let open_coroutine = async {
121125
File::open(url).await
122126
};
123-
124-
FileReader{
127+
128+
FileReader {
125129
path: String::from(url),
126130
file: tokio_block_on(open_coroutine).expect("Can not open file"),
127131
}
@@ -144,7 +148,7 @@ impl Reader for FileReader{
144148
}
145149

146150
#[inline]
147-
fn iter_directory(url: &str) -> Box<dyn GenericIterator<String>>{
151+
fn iter_directory(url: &str) -> Box<dyn GenericIterator<String>> {
148152
Box::new(DirectoryIterator::new(url))
149153
}
150154

@@ -202,4 +206,15 @@ mod tests {
202206
let url = "/tmp/документи/bar/file";
203207
assert_eq!(FileReader::relative_path(src_arg, url), "tmp/документи/bar/file");
204208
}
209+
210+
#[test]
211+
fn test_url_verifier() {
212+
assert!(check_valid_url("The Folder/The File"));
213+
assert!(check_valid_url("Teka/Łukasz"));
214+
assert!(check_valid_url("/home/Łukasz/Pobrane/file.txt"));
215+
assert!(check_valid_url("just_file_name"));
216+
assert!(check_valid_url("просто_файл"));
217+
assert!(check_valid_url("file' name"));
218+
assert!(!check_valid_url("F:\\windows\\not_supported"));
219+
}
205220
}

src/writer/file.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ pub struct FileWriter{
1616
file: File,
1717
}
1818

19+
#[inline]
20+
fn check_valid_url(url: &str) -> bool {
21+
let re = Regex::new(r"^(/?[\s\w'.-]+)+(/)?$").unwrap();
22+
re.is_match(url)
23+
}
24+
1925
#[async_trait]
2026
impl Writer for FileWriter{
2127
fn new(url: &str) -> Self where Self: Sized {
@@ -46,8 +52,7 @@ impl Writer for FileWriter{
4652
}
4753

4854
fn can_write(url: &str) -> bool where Self: Sized {
49-
let re = Regex::new(r"^(/?[\w.-]+)+(/)?$").unwrap();
50-
if !re.is_match(url){
55+
if !check_valid_url(url){
5156
return false;
5257
}
5358
let path = PathBuf::from(url);

0 commit comments

Comments
 (0)