Support escaped spaces in filenames.

This commit is contained in:
Erick Crager 2021-10-10 19:40:40 -05:00 committed by Fabrice Reix
parent b6f8797904
commit b76c5519fe
2 changed files with 64 additions and 3 deletions

View File

@ -331,12 +331,13 @@ pub fn hex(reader: &mut Reader) -> ParseResult<'static, Hex> {
}
pub fn filename(reader: &mut Reader) -> ParseResult<'static, Filename> {
// this is an absolure file
// this is an absolute file
// that you have to write with a relative name
// default root_dir is the hurl directory
let start = reader.state.clone();
let s = reader
.read_while(|c| c.is_alphanumeric() || *c == '.' || *c == '/' || *c == '_' || *c == '-');
let s = reader.read_while_escaping(|c| {
c.is_alphanumeric() || *c == '.' || *c == '/' || *c == '_' || *c == '-'
});
if s.is_empty() {
return Err(Error {
pos: start.pos,
@ -1462,6 +1463,25 @@ mod tests {
},
}
);
let mut reader = Reader::init(r#"file, tmp/filename\ with\ spaces.txt;"#);
assert_eq!(
file(&mut reader).unwrap(),
File {
space0: Whitespace {
value: String::from(" "),
source_info: SourceInfo::init(1, 6, 1, 7),
},
filename: Filename {
value: String::from("tmp/filename with spaces.txt"),
source_info: SourceInfo::init(1, 7, 1, 37),
},
space1: Whitespace {
value: String::from(""),
source_info: SourceInfo::init(1, 37, 1, 37),
},
}
);
}
#[test]
@ -1487,6 +1507,23 @@ mod tests {
value: String::from(";")
}
);
let mut reader = Reader::init(r#"file, tmp/filename\ with\ unescaped .txt;"#);
let error = file(&mut reader).err().unwrap();
assert_eq!(
error.pos,
Pos {
line: 1,
column: 37,
}
);
assert!(!error.recoverable);
assert_eq!(
error.inner,
ParseError::Expecting {
value: String::from(";")
}
);
}
#[test]

View File

@ -81,6 +81,30 @@ impl Reader {
}
}
// only support escaped spaces for now
pub fn read_while_escaping(&mut self, predicate: fn(&char) -> bool) -> String {
let mut s = String::from("");
let mut escaped = false;
loop {
match self.peek() {
None => return s,
Some(c) => {
if escaped && c == ' ' {
escaped = false;
s.push(self.read().unwrap())
} else if c == '\\' {
escaped = true;
let _backslash = self.read().unwrap();
} else if predicate(&c) {
s.push(self.read().unwrap())
} else {
return s;
}
}
}
}
}
// assume that you still have count characters to read in your buffer
pub fn read_n(&mut self, count: usize) -> String {
let mut s = String::from("");