use std::char::from_u32;
use std::fmt;
use std::fs::File;
use std::io::{Cursor, Read, Write};
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::str::from_utf8;
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
use crate::bytecode::{BYTECODE_VERSION, Code};
use crate::bytes::Bytes;
use crate::error::Error;
use crate::exec::Context;
use crate::function::Lambda;
use crate::integer::{Integer, Ratio, Sign};
use crate::io::{IoError, IoMode};
use crate::module::ModuleCode;
use crate::name::{Name, NameDisplay, NameMap, NameSet, NameStore,
NameInputConversion, NameOutputConversion};
use crate::scope::ImportSet;
use crate::structs::{StructDef, StructValueDef};
use crate::value::Value;
pub const MAGIC_NUMBER: &[u8; 4] = b"\0MUR";
#[derive(Debug)]
pub enum DecodeError {
DivisionByZero,
EmptyList,
IncorrectMagicNumber([u8; 4]),
IncorrectVersion(u32),
InvalidChar(u32),
InvalidCodeFlags(u32),
InvalidName(u32),
InvalidParamCount,
InvalidType(u8),
InvalidUtf8,
UnbalancedComma,
UnexpectedEof,
}
impl fmt::Display for DecodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::DecodeError::*;
match *self {
DivisionByZero => f.write_str("zero denominator"),
EmptyList => f.write_str("empty list"),
IncorrectMagicNumber(n) => write!(f,
"incorrect magic number: expected {:?}; found {:?}",
MAGIC_NUMBER, n),
IncorrectVersion(n) => write!(f,
"incorrect version number: expected {:08x}; found {:08x}",
BYTECODE_VERSION, n),
InvalidChar(n) => write!(f, "\\u{{{:x}}} is not a valid char", n),
InvalidCodeFlags(flags) =>
write!(f, "invalid code object flags: {:#x}", flags),
InvalidName(n) => write!(f, "invalid name: {}", n),
InvalidParamCount => f.write_str("invalid parameter count"),
InvalidType(ty) => write!(f, "invalid type {:#x}", ty),
InvalidUtf8 => f.write_str("invalid UTF-8 in string"),
UnbalancedComma => f.write_str("unbalanced quasiquote and comma values"),
UnexpectedEof => f.write_str("unexpected end-of-file"),
}
}
}
impl NameDisplay for DecodeError {
fn fmt(&self, _names: &NameStore, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
#[derive(Debug)]
pub enum EncodeError {
InvalidUtf8,
Overflow,
UnencodableType(&'static str),
UnencodableValue(&'static str),
}
impl fmt::Display for EncodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::EncodeError::*;
match *self {
InvalidUtf8 => f.write_str("invalid utf-8"),
Overflow => f.write_str("integer overflow"),
UnencodableType(ty) => write!(f, "cannot encode value of type `{}`", ty),
UnencodableValue(v) => write!(f, "cannot encode value {}", v),
}
}
}
impl NameDisplay for EncodeError {
fn fmt(&self, _names: &NameStore, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
pub fn read_bytecode_file(path: &Path, ctx: &Context) -> Result<ModuleCode, Error> {
let mut f = File::open(path)
.map_err(|e| IoError::new(IoMode::Open, path, e))?;
read_bytecode(&mut f, path, ctx)
}
pub fn read_bytecode<R: Read>(r: &mut R, path: &Path, ctx: &Context)
-> Result<ModuleCode, Error> {
let mut buf = [0; 4];
r.read_exact(&mut buf)
.map_err(|e| IoError::new(IoMode::Read, path, e))?;
check_magic_number(buf)?;
r.read_exact(&mut buf)
.map_err(|e| IoError::new(IoMode::Read, path, e))?;
check_version(buf)?;
let mut buf = Vec::new();
r.read_to_end(&mut buf)
.map_err(|e| IoError::new(IoMode::Read, path, e))?;
let mut dec = ValueDecoder::new(ctx, &buf);
let n_names = dec.read_uint()?;
let mut names = NameInputConversion::new();
{
let mut name_store = ctx.scope().names().borrow_mut();
for _ in 0..n_names {
let s = dec.read_string()?;
names.insert(name_store.add(s));
}
}
let n_exports = dec.read_uint()?;
let mut exports = NameSet::new();
for _ in 0..n_exports {
let name = dec.read_name(&names)?;
exports.insert(name);
}
let n_imports = dec.read_uint()?;
let mut imports = Vec::new();
for _ in 0..n_imports {
let mod_name = dec.read_name(&names)?;
let mut imp = ImportSet::new(mod_name);
let n_names = dec.read_uint()?;
for _ in 0..n_names {
let src = dec.read_name(&names)?;
let dest = dec.read_name(&names)?;
imp.names.push((src, dest));
}
imports.push(imp);
}
let n_consts = dec.read_uint()?;
let mut consts = Vec::with_capacity(n_consts as usize);
for _ in 0..n_consts {
let name = dec.read_name(&names)?;
let value = dec.read_value(&names)?;
consts.push((name, value));
}
let n_macros = dec.read_uint()?;
let mut macros = Vec::with_capacity(n_macros as usize);
for _ in 0..n_macros {
let name = dec.read_name(&names)?;
let code = Rc::new(dec.read_code(&names)?);
macros.push((name, code));
}
let n_values = dec.read_uint()?;
let mut values = Vec::with_capacity(n_values as usize);
for _ in 0..n_values {
let name = dec.read_name(&names)?;
let value = dec.read_value(&names)?;
values.push((name, value));
}
let doc = dec.read_string()?;
let doc = if doc.is_empty() {
None
} else {
Some(doc.to_owned())
};
let n_docs = dec.read_uint()?;
let mut docs = Vec::with_capacity(n_docs as usize);
for _ in 0..n_docs {
let name = dec.read_name(&names)?;
let doc = dec.read_string()?;
docs.push((name, doc.to_owned()));
}
let mut exprs = Vec::new();
while !dec.is_empty() {
exprs.push(Rc::new(dec.read_code(&names)?));
}
Ok(ModuleCode{
code: exprs,
constants: consts,
macros,
values,
exports: exports.into_slice(),
imports,
module_doc: doc,
docs,
})
}
pub fn write_bytecode_file(path: &Path, module: &ModuleCode,
name_store: &NameStore) -> Result<(), Error> {
let mut f = File::create(path)
.map_err(|e| IoError::new(IoMode::Create, path, e))?;
write_bytecode(&mut f, path, module, name_store)
}
pub fn write_bytecode<W: Write>(w: &mut W, path: &Path, module: &ModuleCode,
name_store: &NameStore) -> Result<(), Error> {
let mut names = NameOutputConversion::new(name_store);
let mut body_enc = ValueEncoder::new();
body_enc.write_len(module.imports.len())?;
for imp in &module.imports {
body_enc.write_name(imp.module_name, &mut names)?;
body_enc.write_len(imp.names.len())?;
for &(src, dest) in &imp.names {
body_enc.write_name(src, &mut names)?;
body_enc.write_name(dest, &mut names)?;
}
}
body_enc.write_len(module.constants.len())?;
for &(name, ref value) in &module.constants {
body_enc.write_name(name, &mut names)?;
body_enc.write_value(value, &mut names)?;
}
body_enc.write_len(module.macros.len())?;
for &(name, ref mac) in &module.macros {
body_enc.write_name(name, &mut names)?;
body_enc.write_code(mac, &mut names)?;
}
body_enc.write_len(module.values.len())?;
for &(name, ref value) in &module.values {
body_enc.write_name(name, &mut names)?;
body_enc.write_value(value, &mut names)?;
}
if let Some(ref doc) = module.module_doc {
body_enc.write_string(doc)?;
} else {
body_enc.write_string("")?;
}
body_enc.write_len(module.docs.len())?;
for &(name, ref doc) in &module.docs {
body_enc.write_name(name, &mut names)?;
body_enc.write_string(doc)?;
}
for code in &module.code {
body_enc.write_code(code, &mut names)?;
}
let mut head_enc = ValueEncoder::new();
head_enc.write_len(names.len())?;
for name in names.names() {
head_enc.write_string(name)?;
}
head_enc.write_len(module.exports.len())?;
for name in &module.exports {
head_enc.write_name(name, &mut names)?;
}
w.write_all(MAGIC_NUMBER)
.map_err(|e| IoError::new(IoMode::Write, path, e))?;
w.write_u32::<BigEndian>(BYTECODE_VERSION)
.map_err(|e| IoError::new(IoMode::Write, path, e))?;
w.write_all(&head_enc.into_bytes())
.and_then(|_| w.write_all(&body_enc.into_bytes()))
.map_err(|e| IoError::new(IoMode::Write, path, e))?;
Ok(())
}
fn check_magic_number(num: [u8; 4]) -> Result<(), DecodeError> {
if &num == MAGIC_NUMBER {
Ok(())
} else {
Err(DecodeError::IncorrectMagicNumber(num))
}
}
fn check_version(num: [u8; 4]) -> Result<(), DecodeError> {
let version = BigEndian::read_u32(&num);
if version == BYTECODE_VERSION {
Ok(())
} else {
Err(DecodeError::IncorrectVersion(version))
}
}
struct ValueDecoder<'a, 'data> {
data: Cursor<&'data [u8]>,
ctx: &'a Context,
}
impl<'a, 'data> ValueDecoder<'a, 'data> {
fn new(ctx: &'a Context, data: &'data [u8]) -> ValueDecoder<'a, 'data> {
ValueDecoder{
data: Cursor::new(data),
ctx,
}
}
fn is_empty(&self) -> bool {
let buf = self.data.get_ref();
self.data.position() as usize == buf.len()
}
fn read_value(&mut self, names: &NameInputConversion) -> Result<Value, DecodeError> {
use self::types::*;
let ty = self.read_u8()?;
match ty {
UNIT => Ok(Value::Unit),
BOOL_TRUE => Ok(Value::Bool(true)),
BOOL_FALSE => Ok(Value::Bool(false)),
FLOAT => Ok(Value::Float(self.read_f64()?)),
INTEGER | INTEGER_NEG => {
let sign = if ty == INTEGER {
Sign::Plus
} else {
Sign::Minus
};
self.read_integer(sign).map(Value::Integer)
}
INTEGER_ZERO => Ok(Value::Integer(Integer::zero())),
RATIO | RATIO_NEG => {
let sign = if ty == RATIO {
Sign::Plus
} else {
Sign::Minus
};
let numer = self.read_integer(sign)?;
let denom = self.read_integer(Sign::Plus)?;
if denom.is_zero() {
Err(DecodeError::DivisionByZero)
} else {
Ok(Ratio::new(numer, denom).into())
}
}
RATIO_ZERO => Ok(Value::Ratio(Ratio::zero())),
NAME => Ok(Value::Name(self.read_name(names)?)),
KEYWORD => Ok(Value::Keyword(self.read_name(names)?)),
CHAR => {
let c = self.read_u32()?;
from_u32(c)
.map(Value::Char)
.ok_or_else(|| DecodeError::InvalidChar(c))
}
STRING => self.read_string().map(|s| s.into()),
BYTES => self.read_byte_string().map(|s| s.into()),
PATH => self.read_string().map(|s| PathBuf::from(s).into()),
STRUCT => Err(DecodeError::InvalidType(STRUCT)),
STRUCT_DEF => {
let name = self.read_name(names)?;
let n = self.read_uint()?;
let mut fields = NameMap::new();
for _ in 0..n {
let field = self.read_name(names)?;
let ty = self.read_name(names)?;
fields.insert(field, ty);
}
let def = StructValueDef::new(fields.into_slice());
Ok(Value::StructDef(Rc::new(StructDef::new(name, Box::new(def)))))
}
QUASI_QUOTE => {
let n = u32::from(self.read_u8()?);
self.read_value(names).map(|v| v.quasiquote(n))
}
QUASI_QUOTE_ONE => self.read_value(names).map(|v| v.quasiquote(1)),
COMMA => {
let n = u32::from(self.read_u8()?);
self.read_value(names).map(|v| v.comma(n))
}
COMMA_ONE => self.read_value(names).map(|v| v.comma(1)),
COMMA_AT => {
let n = u32::from(self.read_u8()?);
self.read_value(names).map(|v| v.comma_at(n))
}
COMMA_AT_ONE => self.read_value(names).map(|v| v.comma_at(1)),
QUOTE => {
let n = u32::from(self.read_u8()?);
self.read_value(names).map(|v| v.quote(n))
}
QUOTE_ONE => self.read_value(names).map(|v| v.quote(1)),
LIST => {
let n = self.read_len()?;
if n == 0 {
return Err(DecodeError::EmptyList);
}
let mut v = Vec::with_capacity(n);
for _ in 0..n {
v.push(self.read_value(names)?);
}
Ok(v.into())
}
LAMBDA => {
let code = self.read_code(names)?;
Ok(Value::Lambda(Lambda::new(Rc::new(code), self.ctx.scope())))
}
_ => Err(DecodeError::InvalidType(ty))
}
}
fn read_bytes(&mut self, n: usize) -> Result<&'data [u8], DecodeError> {
read_cursor(&mut self.data, n).ok_or(DecodeError::UnexpectedEof)
}
fn read_code(&mut self, names: &NameInputConversion) -> Result<Code, DecodeError> {
use crate::bytecode::code_flags::*;
let flags = u32::from(self.read_u8()?);
if flags & ALL_FLAGS != flags {
return Err(DecodeError::InvalidCodeFlags(flags));
}
let name = if flags & HAS_NAME == 0 {
None
} else {
Some(self.read_name(names)?)
};
let doc = if flags & HAS_DOC_STRING == 0 {
None
} else {
Some(self.read_string()?.to_owned())
};
let n_consts = self.read_len()?;
let mut consts = Vec::with_capacity(n_consts);
for _ in 0..n_consts {
let v = self.read_value(names)?;
validate_value(&v)?;
consts.push(v);
}
let code_bytes = self.read_len()?;
let code = self.read_bytes(code_bytes)?.to_vec();
let n_params = self.read_uint()?;
let req_params = self.read_uint()?;
if n_params < req_params {
return Err(DecodeError::InvalidParamCount);
}
let mut kw_params = Vec::new();
match flags & PARAM_FLAGS_MASK {
0 | HAS_REST_PARAMS => (),
HAS_KW_PARAMS => {
let n = self.read_len()?;
if n == 0 {
return Err(DecodeError::InvalidCodeFlags(flags));
}
kw_params.reserve_exact(n);
for _ in 0..n {
kw_params.push(self.read_name(names)?);
}
}
_ => return Err(DecodeError::InvalidCodeFlags(flags))
}
Ok(Code{
name,
consts: consts.into_boxed_slice(),
code: code.into_boxed_slice(),
kw_params: kw_params.into_boxed_slice(),
n_params,
req_params,
flags,
doc,
})
}
fn read_name(&mut self, names: &NameInputConversion) -> Result<Name, DecodeError> {
let n = self.read_uint()?;
names.get(n).ok_or_else(|| DecodeError::InvalidName(n))
}
fn read_string(&mut self) -> Result<&'data str, DecodeError> {
let n = self.read_uint()?;
let b = self.read_bytes(n as usize)?;
from_utf8(b).map_err(|_| DecodeError::InvalidUtf8)
}
fn read_byte_string(&mut self) -> Result<Bytes, DecodeError> {
let n = self.read_uint()?;
let b = self.read_bytes(n as usize)?;
Ok(Bytes::from(b))
}
fn read_integer(&mut self, sign: Sign) -> Result<Integer, DecodeError> {
let n = self.read_uint()?;
let b = self.read_bytes(n as usize)?;
Ok(Integer::from_bytes_be(sign, b))
}
fn read_u8(&mut self) -> Result<u8, DecodeError> {
Ok(self.data.read_u8()
.map_err(|_| DecodeError::UnexpectedEof)?)
}
fn read_u32(&mut self) -> Result<u32, DecodeError> {
Ok(self.data.read_u32::<BigEndian>()
.map_err(|_| DecodeError::UnexpectedEof)?)
}
fn read_len(&mut self) -> Result<usize, DecodeError> {
self.read_uint().map(|n| n as usize)
}
fn read_uint(&mut self) -> Result<u32, DecodeError> {
let hi = u32::from(self.read_u8()?);
if hi & 0x80 == 0 {
Ok(hi)
} else {
let hi = (hi & 0x7f) << 8;
let lo = u32::from(self.read_u8()?);
Ok(hi | lo)
}
}
fn read_f64(&mut self) -> Result<f64, DecodeError> {
Ok(self.data.read_f64::<BigEndian>()
.map_err(|_| DecodeError::UnexpectedEof)?)
}
}
fn validate_value(v: &Value) -> Result<(), DecodeError> {
validate_value_inner(v, 0)
}
fn validate_value_inner(v: &Value, quasi: u32) -> Result<(), DecodeError> {
match *v {
Value::Quasiquote(ref v, n) => validate_value_inner(v, quasi + n),
Value::Comma(ref v, n) | Value::CommaAt(ref v, n) => if n >= quasi {
Err(DecodeError::UnbalancedComma)
} else {
validate_value_inner(v, quasi - n)
},
Value::Quote(ref v, _) => validate_value_inner(v, quasi),
_ => Ok(())
}
}
struct ValueEncoder {
data: Vec<u8>,
}
impl ValueEncoder {
fn new() -> ValueEncoder {
ValueEncoder{
data: Vec::with_capacity(32),
}
}
fn into_bytes(self) -> Vec<u8> {
self.data
}
fn write_value(&mut self, value: &Value, names: &mut NameOutputConversion) -> Result<(), EncodeError> {
use self::types::*;
match *value {
Value::Unit => self.write_u8(UNIT),
Value::Bool(b) => if b {
self.write_u8(BOOL_TRUE);
} else {
self.write_u8(BOOL_FALSE);
},
Value::Float(f) => {
self.write_u8(FLOAT);
self.write_f64(f);
}
Value::Integer(ref i) => {
if i.is_zero() {
self.write_u8(INTEGER_ZERO);
} else {
if i.is_negative() {
self.write_u8(INTEGER_NEG);
} else {
self.write_u8(INTEGER);
}
self.write_integer(i)?;
}
}
Value::Ratio(ref r) => {
if r.is_zero() {
self.write_u8(RATIO_ZERO);
} else {
if r.is_positive() {
self.write_u8(RATIO);
} else {
self.write_u8(RATIO_NEG);
}
self.write_integer(r.numer())?;
self.write_integer(r.denom())?;
}
}
Value::Name(name) => {
self.write_u8(NAME);
self.write_name(name, names)?;
}
Value::Keyword(name) => {
self.write_u8(KEYWORD);
self.write_name(name, names)?;
}
Value::Char(c) => {
self.write_u8(CHAR);
self.write_u32(c as u32);
}
Value::String(ref s) => {
self.write_u8(STRING);
self.write_string(s)?;
}
Value::Bytes(ref s) => {
self.write_u8(BYTES);
self.write_byte_string(s)?;
}
Value::Path(ref p) => {
self.write_u8(PATH);
self.write_path(p)?;
}
Value::Struct(_) => return Err(EncodeError::UnencodableType("struct")),
Value::StructDef(ref def) => {
if let Some(vdef) = def.def().downcast_ref::<StructValueDef>() {
self.write_u8(STRUCT_DEF);
let fields = vdef.fields();
self.write_name(def.name(), names)?;
self.write_len(fields.len())?;
for &(name, ty) in fields {
self.write_name(name, names)?;
self.write_name(ty, names)?;
}
} else {
return Err(EncodeError::UnencodableType("struct-def"));
}
}
Value::Quasiquote(ref v, 1) => {
self.write_u8(QUASI_QUOTE_ONE);
self.write_value(v, names)?;
}
Value::Quasiquote(ref v, n) if n <= 0xff => {
self.write_u8(QUASI_QUOTE);
self.write_u8(n as u8);
self.write_value(v, names)?;
}
Value::Comma(ref v, 1) => {
self.write_u8(COMMA_ONE);
self.write_value(v, names)?;
}
Value::Comma(ref v, n) if n <= 0xff => {
self.write_u8(COMMA);
self.write_u8(n as u8);
self.write_value(v, names)?;
}
Value::CommaAt(ref v, 1) => {
self.write_u8(COMMA_AT_ONE);
self.write_value(v, names)?;
}
Value::CommaAt(ref v, n) if n <= 0xff => {
self.write_u8(COMMA_AT);
self.write_u8(n as u8);
self.write_value(v, names)?;
}
Value::Quote(ref v, 1) => {
self.write_u8(QUOTE_ONE);
self.write_value(v, names)?;
}
Value::Quote(ref v, n) if n <= 0xff => {
self.write_u8(QUOTE);
self.write_u8(n as u8);
self.write_value(v, names)?;
}
Value::Comma(_, _)
| Value::CommaAt(_, _)
| Value::Quasiquote(_, _)
| Value::Quote(_, _) => {
return Err(EncodeError::Overflow);
}
Value::List(ref li) => {
self.write_u8(LIST);
self.write_len(li.len())?;
for v in li {
self.write_value(v, names)?;
}
}
Value::Lambda(ref l) => {
if l.values.is_some() {
return Err(EncodeError::UnencodableValue(
"lambda with enclosed values"));
}
self.write_u8(LAMBDA);
self.write_code(&l.code, names)?;
}
Value::Foreign(_) =>
return Err(EncodeError::UnencodableType("foreign value")),
ref v => return Err(EncodeError::UnencodableType(v.type_name()))
}
Ok(())
}
fn write_bytes(&mut self, b: &[u8]) {
self.data.extend(b);
}
fn write_code(&mut self, code: &Code, names: &mut NameOutputConversion) -> Result<(), EncodeError> {
use crate::bytecode::code_flags::*;
self.write_u8(code.flags as u8);
assert_eq!(code.flags & HAS_NAME != 0, code.name.is_some());
assert_eq!(code.flags & HAS_DOC_STRING != 0, code.doc.is_some());
if let Some(name) = code.name {
self.write_name(name, names)?;
}
if let Some(ref doc) = code.doc {
self.write_string(doc)?;
}
self.write_len(code.consts.len())?;
for c in code.consts.iter() {
self.write_value(c, names)?;
}
self.write_len(code.code.len())?;
self.write_bytes(&code.code);
self.write_uint(code.n_params)?;
self.write_uint(code.req_params)?;
assert_eq!(code.flags & PARAM_FLAGS_MASK == HAS_KW_PARAMS,
!code.kw_params.is_empty());
if !code.kw_params.is_empty() {
self.write_len(code.kw_params.len())?;
for &name in code.kw_params.iter() {
self.write_name(name, names)?;
}
}
Ok(())
}
fn write_integer(&mut self, i: &Integer) -> Result<(), EncodeError> {
let (_, b) = i.to_bytes_be();
self.write_len(b.len())?;
self.write_bytes(&b);
Ok(())
}
fn write_name(&mut self, name: Name, names: &mut NameOutputConversion) -> Result<(), EncodeError> {
let n = names.add(name);
self.write_uint(n)
}
fn write_string(&mut self, s: &str) -> Result<(), EncodeError> {
self.write_len(s.len())?;
self.write_bytes(s.as_bytes());
Ok(())
}
fn write_byte_string(&mut self, b: &[u8]) -> Result<(), EncodeError> {
self.write_len(b.len())?;
self.write_bytes(b);
Ok(())
}
fn write_path(&mut self, p: &Path) -> Result<(), EncodeError> {
match p.to_str() {
Some(s) => self.write_string(s),
None => Err(EncodeError::InvalidUtf8)
}
}
fn write_u8(&mut self, b: u8) {
self.data.push(b);
}
fn write_u32(&mut self, n: u32) {
let _ = self.data.write_u32::<BigEndian>(n);
}
fn write_len(&mut self, n: usize) -> Result<(), EncodeError> {
if n > 0x7fff {
Err(EncodeError::Overflow)
} else {
self.write_uint(n as u32)
}
}
fn write_uint(&mut self, n: u32) -> Result<(), EncodeError> {
if n <= 0x7f {
self.write_u8(n as u8);
Ok(())
} else if n <= 0x7fff {
let hi = (n >> 8) as u8;
let lo = n as u8;
self.write_u8(hi | 0x80);
self.write_u8(lo);
Ok(())
} else {
Err(EncodeError::Overflow)
}
}
fn write_f64(&mut self, f: f64) {
let _ = self.data.write_f64::<BigEndian>(f);
}
}
fn read_cursor<'a>(cur: &mut Cursor<&'a [u8]>, n: usize) -> Option<&'a [u8]> {
let pos = cur.position() as usize;
let bytes = *cur.get_ref();
if bytes.len() < pos + n {
None
} else {
cur.set_position((pos + n) as u64);
Some(&bytes[pos..pos + n])
}
}
macro_rules! types {
( $( $name:ident = $value:expr , )+ ) => {
mod types {
$( pub const $name: u8 = $value; )+
}
}
}
types!{
UNIT = 0,
BOOL_TRUE = 1,
BOOL_FALSE = 2,
FLOAT = 3,
INTEGER = 4,
INTEGER_NEG = 5,
INTEGER_ZERO = 6,
RATIO = 7,
RATIO_NEG = 8,
RATIO_ZERO = 9,
NAME = 10,
KEYWORD = 11,
CHAR = 12,
STRING = 13,
BYTES = 14,
PATH = 15,
STRUCT = 16,
STRUCT_DEF = 17,
QUASI_QUOTE = 18,
QUASI_QUOTE_ONE = 19,
COMMA = 20,
COMMA_ONE = 21,
COMMA_AT = 22,
COMMA_AT_ONE = 23,
QUOTE = 24,
QUOTE_ONE = 25,
LIST = 26,
LAMBDA = 27,
}