udled_tokenizers/
string.rs1use alloc::format;
2use udled::{
3 any, tokenizers::Exclude, AsChar, AsSlice, Buffer, Error, Item, Reader, Tokenizer, TokenizerExt,
4};
5
6#[derive(Debug, Clone, Copy, Default)]
7pub struct Str;
8
9impl<'input, B> Tokenizer<'input, B> for Str
10where
11 B: Buffer<'input>,
12 B::Item: AsChar,
13 B::Source: AsSlice<'input>,
14{
15 type Token = Item<<B::Source as AsSlice<'input>>::Slice>;
16 fn to_token<'a>(&self, reader: &mut Reader<'_, 'input, B>) -> Result<Self::Token, Error> {
17 reader.parse(
18 (
19 '"',
20 ('\\', any!('\\', '\'', '"', 'r', 'n', '0'))
21 .or(Exclude::new('\\'.or('"')))
22 .until('"')
23 .optional(),
24 '"'.map_err(|_, _| format!("Expected unicode string")),
25 )
26 .slice(),
27 )
28 }
29
30 fn peek<'a>(&self, reader: &mut Reader<'_, 'input, B>) -> bool {
31 reader.is('"')
32 }
33}
34
35#[cfg(test)]
36mod test {
37
38 use udled::{Input, Span};
39
40 use super::*;
41
42 #[test]
43 fn empty_string() {
44 let mut input = Input::new(r#""""#);
45 let str = input.parse(Str).unwrap();
46 assert_eq!(str.value, r#""""#);
47 assert_eq!(str.span, Span::new(0, 2));
48 }
49
50 #[test]
51 fn string() {
52 let mut input = Input::new(r#""Hello, World!""#);
53 let str = input.parse(Str).unwrap();
54 assert_eq!(str.value, r#""Hello, World!""#);
55 assert_eq!(str.span, Span::new(0, 15));
56 }
57
58 #[test]
59 fn string_escape() {
60 let mut input = Input::new(r#""Hello, \n World!""#);
61 let str = input.parse(Str).unwrap();
62 assert_eq!(str.value, r#""Hello, \n World!""#);
63 assert_eq!(str.span, Span::new(0, 18));
64 }
65}