use crate::ast::*;
use crate::parser::error::*;
use crate::parser::reader::Reader;
use crate::parser::ParseResult;
pub fn parse(reader: &mut Reader) -> ParseResult<Filename> {
let start = reader.state;
let s = reader.read_while_escaping(|c| {
c.is_alphanumeric() || *c == '.' || *c == '/' || *c == '_' || *c == '-' || *c == ':'
});
if s.is_empty() {
return Err(Error::new(start.pos, false, ParseError::Filename));
}
Ok(Filename {
value: s,
source_info: SourceInfo {
start: start.pos,
end: reader.state.pos,
},
})
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::Pos;
#[test]
fn test_filename() {
let mut reader = Reader::new("data/data.bin");
assert_eq!(
parse(&mut reader).unwrap(),
Filename {
value: String::from("data/data.bin"),
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 14)),
}
);
assert_eq!(reader.state.cursor, 13);
let mut reader = Reader::new("data.bin");
assert_eq!(
parse(&mut reader).unwrap(),
Filename {
value: String::from("data.bin"),
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 9)),
}
);
assert_eq!(reader.state.cursor, 8);
}
#[test]
fn test_include_space() {
let mut reader = Reader::new("file\\ with\\ spaces");
assert_eq!(
parse(&mut reader).unwrap(),
Filename {
value: String::from("file with spaces"),
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 19)),
}
);
assert_eq!(reader.state.cursor, 18);
}
#[test]
fn test_filename_error() {
let mut reader = Reader::new("???");
let error = parse(&mut reader).err().unwrap();
assert_eq!(error.inner, ParseError::Filename);
assert_eq!(error.pos, Pos { line: 1, column: 1 });
}
}