1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use nom::{
    bytes::complete::{tag, take_while1},
    character::complete::char,
    combinator::map,
    sequence::{preceded, terminated},
    IResult,
};

use crate::common::FilePosition;

use super::{
    common::{ws, ws1},
    Span,
};

#[derive(Clone, Debug, PartialEq)]
pub struct Include {
    pub filename: String,
    pub position: FilePosition,
}

pub fn parse_include(input: Span) -> IResult<Span, Include> {
    preceded(
        ws,
        map(
            preceded(
                terminated(tag("include"), ws1),
                terminated(parse_filename, char(';')),
            ),
            |filename| Include {
                filename: filename.to_string(),
                position: filename.into(),
            },
        ),
    )(input)
}

pub fn parse_filename(input: Span) -> IResult<Span, Span> {
    take_while1(|c| c != ';')(input)
}

#[test]
fn test_parse_include() {
    use super::common::assert_parse;
    use super::*;
    let content = "include common.idl;";
    assert_parse(
        parse_include(Span::new(content)),
        Include {
            filename: String::from("common.idl"),
            position: FilePosition { line: 1, column: 9 },
        },
    );
}

#[test]
fn test_parse_include_with_directory() {
    use super::common::assert_parse;
    use super::*;
    let content = "include a/b/c.idl;";
    assert_parse(
        parse_include(Span::new(content)),
        Include {
            filename: String::from("a/b/c.idl"),
            position: FilePosition { line: 1, column: 9 },
        },
    );
}