toml_parser/decoder/
ws.rs1use core::ops::RangeInclusive;
2
3use winnow::stream::ContainsToken as _;
4
5use crate::lexer::COMMENT_START_SYMBOL;
6use crate::ErrorSink;
7use crate::Expected;
8use crate::ParseError;
9use crate::Raw;
10use crate::Span;
11
12pub(crate) fn decode_comment(raw: Raw<'_>, error: &mut dyn ErrorSink) {
24 let s = raw.as_bytes();
25
26 if s.first() != Some(&COMMENT_START_SYMBOL) {
27 error.report_error(
28 ParseError::new("missing comment start")
29 .with_context(Span::new_unchecked(0, raw.len()))
30 .with_expected(&[Expected::Literal("#")])
31 .with_unexpected(Span::new_unchecked(0, 0)),
32 );
33 }
34
35 for (i, b) in s.iter().copied().enumerate() {
36 if !NON_EOL.contains_token(b) {
37 error.report_error(
38 ParseError::new("invalid comment character")
39 .with_context(Span::new_unchecked(0, raw.len()))
40 .with_expected(&[Expected::Description("printable characters")])
41 .with_unexpected(Span::new_unchecked(i, i)),
42 );
43 }
44 }
45}
46
47pub(crate) const NON_ASCII: RangeInclusive<u8> = 0x80..=0xff;
52
53pub(crate) const NON_EOL: (u8, RangeInclusive<u8>, RangeInclusive<u8>) =
55 (0x09, 0x20..=0x7E, NON_ASCII);
56
57pub(crate) fn decode_newline(raw: Raw<'_>, error: &mut dyn ErrorSink) {
66 let s = raw.as_str();
67
68 if s == "\r" {
69 error.report_error(
70 ParseError::new("carriage return must be followed by newline")
71 .with_context(Span::new_unchecked(0, raw.len()))
72 .with_expected(&[Expected::Literal("\n")])
73 .with_unexpected(Span::new_unchecked(raw.len(), raw.len())),
74 );
75 }
76}