use crate::error::{ParseError, ParseErrorKind, PayloadKind};
use crate::source::{SourceLineNumber, SourcePosition};
use super::compact::CompactByte;
use super::rejection::{NonAsciiCodeByte, NonPrintableCodeByte, ReservedSyntaxByte};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct ProgramByte(u8);
impl ProgramByte {
pub(crate) const fn is_valid_raw(raw: u8) -> bool {
raw.is_ascii_graphic() && ReservedSyntaxByte::parse(raw).is_none()
}
pub(crate) const fn from_valid_raw(raw: u8) -> Option<Self> {
if Self::is_valid_raw(raw) {
Some(Self(raw))
} else {
None
}
}
pub(crate) fn parse(
byte: CompactByte,
line_number: SourceLineNumber,
payload_kind: PayloadKind,
) -> Result<Self, ParseError> {
let raw = byte.as_u8();
if let Some(rejected) = NonAsciiCodeByte::parse(raw) {
return Err(ParseError::at_position(
SourcePosition::new(line_number, byte.source_column()),
ParseErrorKind::NonAsciiInCode { byte: rejected },
));
}
if let Some(rejected) = NonPrintableCodeByte::parse(raw) {
return Err(ParseError::at_position(
SourcePosition::new(line_number, byte.source_column()),
ParseErrorKind::NonPrintableAsciiInCode { byte: rejected },
));
}
if let Some(rejected) = ReservedSyntaxByte::parse(raw) {
return Err(ParseError::at_position(
SourcePosition::new(line_number, byte.source_column()),
ParseErrorKind::ReservedSyntaxInPayload {
byte: rejected,
payload_kind,
},
));
}
Ok(Self(raw))
}
pub(crate) const fn get(self) -> u8 {
self.0
}
}