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
16375
pub fn predicate_value(reader: &mut Reader) -> ParseResult<PredicateValue> {
29
16375
    choice(
30
16375
        &[
31
19650
            |p1| match null(p1) {
32
110
                Ok(()) => Ok(PredicateValue::Null),
33
16265
                Err(e) => Err(e),
34
19650
            },
35
19628
            |p1| match boolean(p1) {
36
240
                Ok(value) => Ok(PredicateValue::Bool(value)),
37
16025
                Err(e) => Err(e),
38
19628
            },
39
19580
            |p1| match number(p1) {
40
3925
                Ok(value) => Ok(PredicateValue::Number(value)),
41
12100
                Err(e) => Err(e),
42
19580
            },
43
18795
            |p1| match file(p1) {
44
60
                Ok(value) => Ok(PredicateValue::File(value)),
45
12040
                Err(e) => Err(e),
46
18795
            },
47
18783
            |p1| match hex(p1) {
48
1060
                Ok(value) => Ok(PredicateValue::Hex(value)),
49
10980
                Err(e) => Err(e),
50
18783
            },
51
18571
            |p1| match base64(p1) {
52
35
                Ok(value) => Ok(PredicateValue::Base64(value)),
53
10945
                Err(e) => Err(e),
54
18571
            },
55
18564
            |p1| match placeholder::parse(p1) {
56
455
                Ok(value) => Ok(PredicateValue::Placeholder(value)),
57
10490
                Err(e) => Err(e),
58
18564
            },
59
18473
            |p1| match quoted_template(p1) {
60
10000
                Ok(value) => Ok(PredicateValue::String(value)),
61
490
                Err(e) => Err(e),
62
18473
            },
63
16471
            |p1| match multiline_string(p1) {
64
190
                Ok(value) => Ok(PredicateValue::MultilineString(value)),
65
290
                Err(e) => Err(e),
66
16471
            },
67
16433
            |p1| match backtick_template(p1) {
68
40
                Ok(value) => Ok(PredicateValue::String(value)),
69
250
                Err(e) => Err(e),
70
16433
            },
71
16425
            |p1| match regex(p1) {
72
240
                Ok(value) => Ok(PredicateValue::Regex(value)),
73
10
                Err(e) => Err(e),
74
16425
            },
75
16375
        ],
76
16375
        reader,
77
16375
    )
78
16379
    .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
16379
    })
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
}