use qubit_utils::nonzero;
use crate::internal::ParseError;
#[derive(Debug, Clone, Copy)]
pub(crate) enum CStringLiteralParseContext<'a> {
CompleteText(&'a str),
EofBytes,
StreamingBytes,
}
impl CStringLiteralParseContext<'_> {
#[inline(always)]
pub(crate) fn is_complete_text(self) -> bool {
matches!(self, Self::CompleteText(_) | Self::EofBytes)
}
#[inline(always)]
pub(crate) fn is_streaming(self) -> bool {
matches!(self, Self::StreamingBytes)
}
pub(crate) fn trailing_escape_error(self, marker_index: usize, _available: usize) -> ParseError {
match self {
Self::CompleteText(_) | Self::EofBytes => {
crate::c_string_literal_codec::invalid_escape(marker_index, "\\", "incomplete escape sequence").into()
}
Self::StreamingBytes => ParseError::Incomplete { required: nonzero(2) },
}
}
pub(crate) fn source_character(self, input: &[u8], index: usize) -> char {
match self {
Self::CompleteText(text) => text
.get(index..)
.and_then(|rest| rest.chars().next())
.unwrap_or(char::from(input[index])),
Self::EofBytes | Self::StreamingBytes => char::from(input[index]),
}
}
#[inline(always)]
pub(crate) fn raw_source_reason(self) -> &'static str {
match self {
Self::CompleteText(_) | Self::EofBytes => {
"raw source character must be printable ASCII or allowed whitespace"
}
Self::StreamingBytes => "raw source byte must be printable ASCII or allowed whitespace",
}
}
pub(crate) fn escape_fragment(self, input: &[u8], start: usize, end: usize) -> String {
match self {
Self::CompleteText(text) => text.get(start..end).or(text.get(start..)).unwrap_or("\\").to_owned(),
Self::EofBytes | Self::StreamingBytes => input[start..end.min(input.len())]
.iter()
.map(|byte| char::from(*byte))
.collect(),
}
}
}