1
/*
2
 * Hurl (https://hurl.dev)
3
 * Copyright (C) 2025 Orange
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 *          http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
use super::{expr, ParseResult};
19
use crate::ast::Placeholder;
20
use crate::parser::primitives::{literal, try_literal, zero_or_more_spaces};
21
use crate::reader::Reader;
22

            
23
/// Parse a placeholder {{ expr }}
24
105430
pub fn parse(reader: &mut Reader) -> ParseResult<Placeholder> {
25
105430
    try_literal("{{", reader)?;
26
1285
    let space0 = zero_or_more_spaces(reader)?;
27
1285
    let expr = expr::parse(reader)?;
28
1285
    let space1 = zero_or_more_spaces(reader)?;
29
1285
    literal("}}", reader)?;
30
1285
    Ok(Placeholder {
31
1285
        space0,
32
1285
        expr,
33
1285
        space1,
34
1285
    })
35
}
36

            
37
#[cfg(test)]
38
mod tests {
39
    use super::*;
40
    use crate::ast::{Expr, ExprKind, SourceInfo, Variable, Whitespace};
41
    use crate::parser::ParseErrorKind;
42
    use crate::reader::Pos;
43

            
44
    #[test]
45
    fn test_ok() {
46
        let mut reader = Reader::new("{{ name}}");
47
        assert_eq!(
48
            parse(&mut reader).unwrap(),
49
            Placeholder {
50
                space0: Whitespace {
51
                    value: String::from(" "),
52
                    source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 4)),
53
                },
54
                expr: Expr {
55
                    kind: ExprKind::Variable(Variable {
56
                        name: "name".to_string(),
57
                        source_info: SourceInfo::new(Pos::new(1, 4), Pos::new(1, 8)),
58
                    }),
59
                    source_info: SourceInfo::new(Pos::new(1, 4), Pos::new(1, 8)),
60
                },
61
                space1: Whitespace {
62
                    value: String::new(),
63
                    source_info: SourceInfo::new(Pos::new(1, 8), Pos::new(1, 8)),
64
                },
65
            }
66
        );
67
    }
68

            
69
    #[test]
70
    fn test_error() {
71
        let mut reader = Reader::new("{{host>}}");
72
        let error = parse(&mut reader).err().unwrap();
73
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
74
        assert_eq!(
75
            error.kind,
76
            ParseErrorKind::Expecting {
77
                value: String::from("}}")
78
            }
79
        );
80
        assert!(!error.recoverable);
81
    }
82

            
83
    #[test]
84
    fn test_error_eof() {
85
        let mut reader = Reader::new("{{host");
86
        let error = parse(&mut reader).err().unwrap();
87
        assert_eq!(error.pos, Pos { line: 1, column: 7 });
88
        assert_eq!(
89
            error.kind,
90
            ParseErrorKind::Expecting {
91
                value: String::from("}}")
92
            }
93
        );
94
        assert!(!error.recoverable);
95
    }
96
}