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
17465
pub fn predicate_value(reader: &mut Reader) -> ParseResult<PredicateValue> {
29
17465
    choice(
30
17465
        &[
31
20958
            |p1| match null(p1) {
32
110
                Ok(()) => Ok(PredicateValue::Null),
33
17355
                Err(e) => Err(e),
34
20958
            },
35
20936
            |p1| match boolean(p1) {
36
240
                Ok(value) => Ok(PredicateValue::Bool(value)),
37
17115
                Err(e) => Err(e),
38
20936
            },
39
20888
            |p1| match number(p1) {
40
4155
                Ok(value) => Ok(PredicateValue::Number(value)),
41
12960
                Err(e) => Err(e),
42
20888
            },
43
20057
            |p1| match file(p1) {
44
60
                Ok(value) => Ok(PredicateValue::File(value)),
45
12900
                Err(e) => Err(e),
46
20057
            },
47
20045
            |p1| match hex(p1) {
48
1175
                Ok(value) => Ok(PredicateValue::Hex(value)),
49
11725
                Err(e) => Err(e),
50
20045
            },
51
19810
            |p1| match base64(p1) {
52
35
                Ok(value) => Ok(PredicateValue::Base64(value)),
53
11690
                Err(e) => Err(e),
54
19810
            },
55
19803
            |p1| match placeholder::parse(p1) {
56
585
                Ok(value) => Ok(PredicateValue::Placeholder(value)),
57
11105
                Err(e) => Err(e),
58
19803
            },
59
19686
            |p1| match quoted_template(p1) {
60
10590
                Ok(value) => Ok(PredicateValue::String(value)),
61
515
                Err(e) => Err(e),
62
19686
            },
63
17566
            |p1| match multiline_string(p1) {
64
190
                Ok(value) => Ok(PredicateValue::MultilineString(value)),
65
315
                Err(e) => Err(e),
66
17566
            },
67
17528
            |p1| match backtick_template(p1) {
68
40
                Ok(value) => Ok(PredicateValue::String(value)),
69
275
                Err(e) => Err(e),
70
17528
            },
71
17520
            |p1| match regex(p1) {
72
265
                Ok(value) => Ok(PredicateValue::Regex(value)),
73
10
                Err(e) => Err(e),
74
17520
            },
75
17465
        ],
76
17465
        reader,
77
17465
    )
78
17469
    .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
17469
    })
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
}