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 crate::ast::Bytes;
19
use crate::combinator::choice;
20
use crate::parser::json::parse as parse_json;
21
use crate::parser::multiline::multiline_string;
22
use crate::parser::string::backtick_template;
23
use crate::parser::{primitives, xml, ParseResult};
24
use crate::reader::Reader;
25

            
26
27530
pub fn bytes(reader: &mut Reader) -> ParseResult<Bytes> {
27
27530
    choice(
28
27530
        &[
29
27530
            multiline_string_bytes,
30
27530
            string_bytes,
31
27530
            json_bytes,
32
27530
            xml_bytes,
33
27530
            base64_bytes,
34
27530
            hex_bytes,
35
27530
            file_bytes,
36
27530
        ],
37
27530
        reader,
38
27530
    )
39
}
40

            
41
24950
fn xml_bytes(reader: &mut Reader) -> ParseResult<Bytes> {
42
24950
    match xml::parse(reader) {
43
24845
        Err(e) => Err(e),
44
105
        Ok(value) => Ok(Bytes::Xml(value)),
45
    }
46
}
47

            
48
25335
fn json_bytes(reader: &mut Reader) -> ParseResult<Bytes> {
49
25335
    match parse_json(reader) {
50
24990
        Err(e) => Err(e),
51
345
        Ok(value) => Ok(Bytes::Json(value)),
52
    }
53
}
54

            
55
24375
fn file_bytes(reader: &mut Reader) -> ParseResult<Bytes> {
56
24375
    primitives::file(reader).map(Bytes::File)
57
}
58

            
59
24840
fn base64_bytes(reader: &mut Reader) -> ParseResult<Bytes> {
60
24840
    primitives::base64(reader).map(Bytes::Base64)
61
}
62

            
63
24555
fn hex_bytes(reader: &mut Reader) -> ParseResult<Bytes> {
64
24555
    primitives::hex(reader).map(Bytes::Hex)
65
}
66

            
67
27530
pub fn multiline_string_bytes(reader: &mut Reader) -> ParseResult<Bytes> {
68
27530
    multiline_string(reader).map(Bytes::MultilineString)
69
}
70

            
71
26850
fn string_bytes(reader: &mut Reader) -> ParseResult<Bytes> {
72
26850
    backtick_template(reader).map(Bytes::OnelineString)
73
}
74

            
75
#[cfg(test)]
76
mod tests {
77
    use super::super::error::*;
78
    use super::*;
79
    use crate::ast::{JsonListElement, JsonValue, SourceInfo, Template, TemplateElement};
80
    use crate::reader::Pos;
81
    use crate::typing::ToSource;
82

            
83
    #[test]
84
    fn test_bytes_json() {
85
        let mut reader = Reader::new("[1,2,3] ");
86
        assert_eq!(
87
            bytes(&mut reader).unwrap(),
88
            Bytes::Json(JsonValue::List {
89
                space0: String::new(),
90
                elements: vec![
91
                    JsonListElement {
92
                        space0: String::new(),
93
                        value: JsonValue::Number("1".to_string()),
94
                        space1: String::new(),
95
                    },
96
                    JsonListElement {
97
                        space0: String::new(),
98
                        value: JsonValue::Number("2".to_string()),
99
                        space1: String::new(),
100
                    },
101
                    JsonListElement {
102
                        space0: String::new(),
103
                        value: JsonValue::Number("3".to_string()),
104
                        space1: String::new(),
105
                    },
106
                ],
107
            })
108
        );
109
        assert_eq!(reader.cursor().index, 7);
110

            
111
        let mut reader = Reader::new("{ } ");
112
        assert_eq!(
113
            bytes(&mut reader).unwrap(),
114
            Bytes::Json(JsonValue::Object {
115
                space0: " ".to_string(),
116
                elements: vec![],
117
            })
118
        );
119
        assert_eq!(reader.cursor().index, 3);
120

            
121
        let mut reader = Reader::new("true");
122
        assert_eq!(
123
            bytes(&mut reader).unwrap(),
124
            Bytes::Json(JsonValue::Boolean(true))
125
        );
126
        assert_eq!(reader.cursor().index, 4);
127

            
128
        let mut reader = Reader::new("\"\" x");
129
        let template = Template::new(
130
            Some('"'),
131
            vec![],
132
            SourceInfo::new(Pos::new(1, 2), Pos::new(1, 2)),
133
        );
134
        assert_eq!(
135
            bytes(&mut reader).unwrap(),
136
            Bytes::Json(JsonValue::String(template))
137
        );
138
        assert_eq!(reader.cursor().index, 2);
139
    }
140

            
141
    #[test]
142
    fn test_bytes_xml() {
143
        let mut reader = Reader::new("<a/>");
144
        assert_eq!(
145
            bytes(&mut reader).unwrap(),
146
            Bytes::Xml(String::from("<a/>"))
147
        );
148
    }
149

            
150
    #[test]
151
    fn test_bytes_json_error() {
152
        let mut reader = Reader::new("{ x ");
153
        let error = bytes(&mut reader).err().unwrap();
154
        assert_eq!(error.pos, Pos { line: 1, column: 3 });
155
        assert_eq!(
156
            error.kind,
157
            ParseErrorKind::Expecting {
158
                value: "\"".to_string()
159
            },
160
        );
161
    }
162

            
163
    #[test]
164
    fn test_bytes_multilines_error() {
165
        let mut reader = Reader::new("```\nxxx ");
166
        let error = bytes(&mut reader).err().unwrap();
167
        assert_eq!(error.pos, Pos { line: 2, column: 5 });
168
        assert_eq!(
169
            error.kind,
170
            ParseErrorKind::Expecting {
171
                value: "```".to_string()
172
            }
173
        );
174
    }
175

            
176
    #[test]
177
    fn test_bytes_eof() {
178
        let mut reader = Reader::new("");
179
        let error = bytes(&mut reader).err().unwrap();
180
        assert_eq!(
181
            error.kind,
182
            ParseErrorKind::Expecting {
183
                value: String::from("file")
184
            }
185
        );
186
        assert!(error.recoverable);
187
    }
188

            
189
    #[test]
190
    fn test_json_bytes() {
191
        let mut reader = Reader::new("100");
192
        assert_eq!(
193
            json_bytes(&mut reader).unwrap(),
194
            Bytes::Json(JsonValue::Number("100".to_string()))
195
        );
196
    }
197

            
198
    #[test]
199
    fn test_bytes_string() {
200
        let mut reader = Reader::new("`foo`  ");
201
        let template = Template::new(
202
            Some('`'),
203
            vec![TemplateElement::String {
204
                value: "foo".to_string(),
205
                source: "foo".to_source(),
206
            }],
207
            SourceInfo::new(Pos::new(1, 1), Pos::new(1, 6)),
208
        );
209
        assert_eq!(bytes(&mut reader).unwrap(), Bytes::OnelineString(template));
210
        assert_eq!(reader.cursor().index, 5);
211
    }
212
}