preserves/implementations/rust/preserves/src/value/packed/constants.rs

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,
}
}
}