90 lines
2.4 KiB
Rust
90 lines
2.4 KiB
Rust
use std::convert::{TryFrom, From};
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
pub enum Tag {
|
|
False,
|
|
True,
|
|
Float,
|
|
Double,
|
|
End,
|
|
Annotation,
|
|
Embedded,
|
|
SmallInteger(i8),
|
|
MediumInteger(u8),
|
|
SignedInteger,
|
|
String,
|
|
ByteString,
|
|
Symbol,
|
|
Record,
|
|
Sequence,
|
|
Set,
|
|
Dictionary,
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
pub struct InvalidTag(u8);
|
|
|
|
impl From<InvalidTag> for std::io::Error {
|
|
fn from(v: InvalidTag) -> Self {
|
|
std::io::Error::new(std::io::ErrorKind::InvalidData,
|
|
format!("Invalid Preserves tag {}", v.0))
|
|
}
|
|
}
|
|
|
|
impl From<InvalidTag> for crate::error::Error {
|
|
fn from(v: InvalidTag) -> Self {
|
|
crate::error::Error::Io(v.into())
|
|
}
|
|
}
|
|
|
|
impl TryFrom<u8> for Tag {
|
|
type Error = InvalidTag;
|
|
fn try_from(v: u8) -> Result<Self, Self::Error> {
|
|
match v {
|
|
0x80 => Ok(Self::False),
|
|
0x81 => Ok(Self::True),
|
|
0x82 => Ok(Self::Float),
|
|
0x83 => Ok(Self::Double),
|
|
0x84 => Ok(Self::End),
|
|
0x85 => Ok(Self::Annotation),
|
|
0x86 => Ok(Self::Embedded),
|
|
0x90..=0x9c => Ok(Self::SmallInteger((v - 0x90) as i8)),
|
|
0x9d..=0x9f => Ok(Self::SmallInteger((v - 0x90) as i8 - 16)),
|
|
0xa0..=0xaf => Ok(Self::MediumInteger(v - 0xa0 + 1)),
|
|
0xb0 => Ok(Self::SignedInteger),
|
|
0xb1 => Ok(Self::String),
|
|
0xb2 => Ok(Self::ByteString),
|
|
0xb3 => Ok(Self::Symbol),
|
|
0xb4 => Ok(Self::Record),
|
|
0xb5 => Ok(Self::Sequence),
|
|
0xb6 => Ok(Self::Set),
|
|
0xb7 => Ok(Self::Dictionary),
|
|
_ => Err(InvalidTag(v))
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Tag> for u8 {
|
|
fn from(v: Tag) -> Self {
|
|
match v {
|
|
Tag::False => 0x80,
|
|
Tag::True => 0x81,
|
|
Tag::Float => 0x82,
|
|
Tag::Double => 0x83,
|
|
Tag::End => 0x84,
|
|
Tag::Annotation => 0x85,
|
|
Tag::Embedded => 0x86,
|
|
Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 },
|
|
Tag::MediumInteger(count) => count - 1 + 0xa0,
|
|
Tag::SignedInteger => 0xb0,
|
|
Tag::String => 0xb1,
|
|
Tag::ByteString => 0xb2,
|
|
Tag::Symbol => 0xb3,
|
|
Tag::Record => 0xb4,
|
|
Tag::Sequence => 0xb5,
|
|
Tag::Set => 0xb6,
|
|
Tag::Dictionary => 0xb7,
|
|
}
|
|
}
|
|
}
|