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::placeholder;
19
use crate::ast::PredicateValue;
20
use crate::combinator::choice;
21
use crate::parser::multiline::multiline_string;
22
use crate::parser::number::number;
23
use crate::parser::primitives::{base64, boolean, file, hex, null, regex};
24
use crate::parser::string::{backtick_template, quoted_template};
25
use crate::parser::{ParseError, ParseErrorKind, ParseResult};
26
use crate::reader::Reader;
27

            
28
18135
pub fn predicate_value(reader: &mut Reader) -> ParseResult<PredicateValue> {
29
18135
    choice(
30
        &[
31
18135
            |p1| match null(p1) {
32
115
                Ok(()) => Ok(PredicateValue::Null),
33
18020
                Err(e) => Err(e),
34
18135
            },
35
18020
            |p1| match boolean(p1) {
36
245
                Ok(value) => Ok(PredicateValue::Bool(value)),
37
17775
                Err(e) => Err(e),
38
18020
            },
39
17775
            |p1| match number(p1) {
40
4395
                Ok(value) => Ok(PredicateValue::Number(value)),
41
13380
                Err(e) => Err(e),
42
17775
            },
43
13380
            |p1| match file(p1) {
44
65
                Ok(value) => Ok(PredicateValue::File(value)),
45
13315
                Err(e) => Err(e),
46
13380
            },
47
13315
            |p1| match hex(p1) {
48
1220
                Ok(value) => Ok(PredicateValue::Hex(value)),
49
12095
                Err(e) => Err(e),
50
13315
            },
51
12095
            |p1| match base64(p1) {
52
40
                Ok(value) => Ok(PredicateValue::Base64(value)),
53
12055
                Err(e) => Err(e),
54
12095
            },
55
12055
            |p1| match placeholder::parse(p1) {
56
590
                Ok(value) => Ok(PredicateValue::Placeholder(value)),
57
11465
                Err(e) => Err(e),
58
12055
            },
59
11465
            |p1| match quoted_template(p1) {
60
10890
                Ok(value) => Ok(PredicateValue::String(value)),
61
575
                Err(e) => Err(e),
62
11465
            },
63
565
            |p1| match multiline_string(p1) {
64
220
                Ok(value) => Ok(PredicateValue::MultilineString(value)),
65
345
                Err(e) => Err(e),
66
565
            },
67
345
            |p1| match backtick_template(p1) {
68
40
                Ok(value) => Ok(PredicateValue::String(value)),
69
305
                Err(e) => Err(e),
70
345
            },
71
305
            |p1| match regex(p1) {
72
295
                Ok(value) => Ok(PredicateValue::Regex(value)),
73
10
                Err(e) => Err(e),
74
305
            },
75
        ],
76
18135
        reader,
77
    )
78
18139
    .map_err(|e| {
79
20
        let kind = if e.recoverable {
80
5
            ParseErrorKind::PredicateValue
81
        } else {
82
15
            e.kind
83
        };
84
20
        ParseError::new(e.pos, false, kind)
85
20
    })
86
}
87

            
88
#[cfg(test)]
89
mod tests {
90
    use super::*;
91
    use crate::ast::{Float, Number, I64};
92
    use crate::parser::ParseErrorKind;
93
    use crate::reader::Pos;
94
    use crate::typing::ToSource;
95

            
96
    #[test]
97
    fn test_predicate_value() {
98
        let mut reader = Reader::new("true");
99
        assert_eq!(
100
            predicate_value(&mut reader).unwrap(),
101
            PredicateValue::Bool(true)
102
        );
103

            
104
        let mut reader = Reader::new("1");
105
        assert_eq!(
106
            predicate_value(&mut reader).unwrap(),
107
            PredicateValue::Number(Number::Integer(I64::new(1, "1".to_source())))
108
        );
109

            
110
        let mut reader = Reader::new("1.1");
111
        assert_eq!(
112
            predicate_value(&mut reader).unwrap(),
113
            PredicateValue::Number(Number::Float(Float::new(1.1, "1.1".to_source())))
114
        );
115
    }
116

            
117
    #[test]
118
    fn test_predicate_value_error() {
119
        let mut reader = Reader::new("xx");
120
        let error = predicate_value(&mut reader).err().unwrap();
121
        assert_eq!(error.pos, Pos { line: 1, column: 1 });
122
        assert_eq!(error.kind, ParseErrorKind::PredicateValue);
123
        assert!(!error.recoverable);
124
    }
125

            
126
    #[test]
127
    fn test_predicate_value_error_missing_quote() {
128
        let mut reader = Reader::new("\"not_found");
129
        let error = predicate_value(&mut reader).err().unwrap();
130
        assert_eq!(
131
            error.pos,
132
            Pos {
133
                line: 1,
134
                column: 11
135
            }
136
        );
137
        assert_eq!(
138
            error.kind,
139
            ParseErrorKind::Expecting {
140
                value: "\"".to_string()
141
            }
142
        );
143
        assert!(!error.recoverable);
144
    }
145
}