Smaller Record; also, use u128/i128 when possible
This commit is contained in:
parent
1f4adc5ba6
commit
bffbeb2f6e
|
@ -27,13 +27,15 @@ pub enum ExpectedKind {
|
|||
Float,
|
||||
Double,
|
||||
|
||||
SignedIntegerI128,
|
||||
SignedIntegerU128,
|
||||
SignedInteger,
|
||||
String,
|
||||
ByteString,
|
||||
Symbol,
|
||||
|
||||
Record(Option<usize>),
|
||||
SimpleRecord(&'static str, Option<usize>),
|
||||
SimpleRecord(String, Option<usize>),
|
||||
Sequence,
|
||||
Set,
|
||||
Dictionary,
|
||||
|
|
|
@ -147,8 +147,7 @@ mod ieee754_section_5_10_total_order_tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod value_tests {
|
||||
use crate::value::{Value, PlainValue};
|
||||
use num::bigint::BigInt;
|
||||
use crate::value::{Value, PlainValue, value::Record, signed_integer::SignedInteger};
|
||||
use super::dom::Dom;
|
||||
|
||||
type VV = Value<PlainValue<Dom>, Dom>;
|
||||
|
@ -179,11 +178,9 @@ mod value_tests {
|
|||
#[test] fn signedinteger_mut() {
|
||||
let mut i = VV::from(123);
|
||||
assert!(i.is_signedinteger());
|
||||
*(i.as_signedinteger_mut().unwrap()) = BigInt::from(234);
|
||||
*(i.as_signedinteger_mut().unwrap()) = SignedInteger::from(234i128);
|
||||
assert_eq!(i, VV::from(234));
|
||||
|
||||
use num::traits::cast::ToPrimitive;
|
||||
assert_eq!(i.as_signedinteger().unwrap().to_i64().unwrap(), 234);
|
||||
assert_eq!(i.as_i().unwrap(), 234);
|
||||
}
|
||||
|
||||
#[test] fn string_mut() {
|
||||
|
@ -209,13 +206,13 @@ mod value_tests {
|
|||
|
||||
#[test] fn record_mut() {
|
||||
let says = VV::symbol("says").wrap();
|
||||
let mut r = VV::record(says.clone(), vec![VV::from("Tony").wrap(), VV::from("Hello!").wrap()]);
|
||||
let mut r = VV::Record(Record(vec![says.clone(), VV::from("Tony").wrap(), VV::from("Hello!").wrap()]));
|
||||
assert_eq!(r.as_record_mut(Some(0)), None);
|
||||
assert_eq!(r.as_record_mut(Some(1)), None);
|
||||
assert!(r.as_record_mut(Some(2)).is_some());
|
||||
assert_eq!(r.as_record_mut(Some(3)), None);
|
||||
r.as_record_mut(None).unwrap().1[0] = VV::from("Alice").wrap();
|
||||
assert_eq!(r, VV::record(says, vec![VV::from("Alice").wrap(), VV::from("Hello!").wrap()]));
|
||||
r.as_record_mut(None).unwrap().fields_mut()[0] = VV::from("Alice").wrap();
|
||||
assert_eq!(r, VV::Record(Record(vec![says, VV::from("Alice").wrap(), VV::from("Hello!").wrap()])));
|
||||
}
|
||||
|
||||
#[test] fn sequence_mut() {
|
||||
|
@ -275,9 +272,9 @@ mod decoder_tests {
|
|||
assert_eq!(buf.len(), 12);
|
||||
let mut d = decoder::from_bytes(&mut buf);
|
||||
assert_eq!(d.read.source.index, 0);
|
||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record("Ping", vec![]));
|
||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Ping"));
|
||||
assert_eq!(d.read.source.index, 6);
|
||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record("Pong", vec![]));
|
||||
assert_eq!(d.demand_next().unwrap().value(), &Value::simple_record0("Pong"));
|
||||
assert_eq!(d.read.source.index, 12);
|
||||
assert!(d.next().is_none());
|
||||
assert!(if let Err(e) = d.demand_next() { is_eof_io_error(&e) } else { false });
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::value::value::{Float, Double};
|
||||
use crate::value::{Value, NestedValue, IOValue, UnwrappedIOValue, Map};
|
||||
use crate::error::{Error, ExpectedKind, Received};
|
||||
use num::traits::cast::ToPrimitive;
|
||||
use serde::Deserialize;
|
||||
use serde::de::{Visitor, SeqAccess, MapAccess, EnumAccess, VariantAccess, DeserializeSeed};
|
||||
use std::iter::Iterator;
|
||||
|
@ -43,14 +42,6 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
|
|||
Value::Boolean(b) => visitor.visit_bool(*b),
|
||||
Value::Float(Float(f)) => visitor.visit_f32(*f),
|
||||
Value::Double(Double(d)) => visitor.visit_f64(*d),
|
||||
Value::SignedInteger(ref i) =>
|
||||
match i.to_i64() {
|
||||
None => match i.to_u64() {
|
||||
None => Err(Error::NumberOutOfRange(i.clone())),
|
||||
Some(n) => visitor.visit_u64(n),
|
||||
}
|
||||
Some(n) => visitor.visit_i64(n),
|
||||
}
|
||||
Value::String(ref s) => visitor.visit_str(&s),
|
||||
Value::ByteString(_) => self.deserialize_bytes(visitor),
|
||||
Value::Record(_) =>
|
||||
|
@ -67,7 +58,16 @@ impl<'de, 'a> serde::de::Deserializer<'de> for &'a mut Deserializer<'de>
|
|||
}
|
||||
Value::Sequence(ref v) => visitor.visit_seq(VecSeq::new(self, v.iter())),
|
||||
Value::Dictionary(ref d) => visitor.visit_map(DictMap::new(self, d)),
|
||||
_ => Err(Error::CannotDeserializeAny),
|
||||
_ => match v.as_i64() {
|
||||
Some(i) => visitor.visit_i64(i),
|
||||
None => match v.as_u64() {
|
||||
Some(u) => visitor.visit_u64(u),
|
||||
None => match v.as_signedinteger() {
|
||||
Some(n) => Err(Error::NumberOutOfRange(n.into())),
|
||||
None => Err(Error::CannotDeserializeAny),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,9 +328,9 @@ impl<'a, 'de> EnumAccess<'de> for &'a mut Deserializer<'de> {
|
|||
fn variant_seed<V>(self, seed: V)
|
||||
-> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>
|
||||
{
|
||||
let (lp, _) = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?;
|
||||
let r = self.check(|v| v.as_record(None), ExpectedKind::Record(None))?;
|
||||
let v = self.input;
|
||||
self.input = IOValue::boxunwrap(lp);
|
||||
self.input = r.label();
|
||||
let variant = seed.deserialize(&mut *self)?;
|
||||
self.input = v;
|
||||
Ok((variant, self))
|
||||
|
@ -345,18 +345,18 @@ impl<'a, 'de> VariantAccess<'de> for &'a mut Deserializer<'de> {
|
|||
}
|
||||
|
||||
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value> where T: DeserializeSeed<'de> {
|
||||
let (_, fs) = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?;
|
||||
self.input = &fs[0];
|
||||
let r = self.check(|v| v.as_record(Some(1)), ExpectedKind::Record(Some(1)))?;
|
||||
self.input = &r.fields()[0];
|
||||
seed.deserialize(&mut *self)
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value> where V: Visitor<'de> {
|
||||
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(None).unwrap().1.iter()))
|
||||
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(None).unwrap().fields().iter()))
|
||||
}
|
||||
|
||||
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V)
|
||||
-> Result<V::Value> where V: Visitor<'de>
|
||||
{
|
||||
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(Some(fields.len())).unwrap().1.iter()))
|
||||
visitor.visit_seq(VecSeq::new(self, self.input.value().as_record(Some(fields.len())).unwrap().fields().iter()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::value::{Value, NestedValue, Domain, IOValue, UnwrappedIOValue, Float, Double};
|
||||
use super::signed_integer::SignedIntegerRepr;
|
||||
use super::writer::Writer;
|
||||
|
||||
pub use super::writer::Result;
|
||||
|
@ -31,14 +32,18 @@ impl<'a, W: Writer> Encoder<'a, W> {
|
|||
Value::Boolean(b) => self.write.write_bool(*b),
|
||||
Value::Float(Float(f)) => self.write.write_f32(*f),
|
||||
Value::Double(Double(d)) => self.write.write_f64(*d),
|
||||
Value::SignedInteger(ref b) => self.write.write_int(b),
|
||||
Value::SignedInteger(n) => match n.repr() {
|
||||
SignedIntegerRepr::I128(i) => self.write.write_i128(*i),
|
||||
SignedIntegerRepr::U128(u) => self.write.write_u128(*u),
|
||||
SignedIntegerRepr::Big(ref n) => self.write.write_int(n),
|
||||
}
|
||||
Value::String(ref s) => self.write.write_string(s),
|
||||
Value::ByteString(ref bs) => self.write.write_bytes(bs),
|
||||
Value::Symbol(ref s) => self.write.write_symbol(s),
|
||||
Value::Record((ref l, ref fs)) => {
|
||||
self.write.open_record(fs.len())?;
|
||||
self.write(IOValue::boxunwrap(l))?;
|
||||
for f in fs { self.write(f)?; }
|
||||
Value::Record(r) => {
|
||||
self.write.open_record(r.arity())?;
|
||||
self.write(r.label())?;
|
||||
for f in r.fields() { self.write(f)?; }
|
||||
self.write.close_record()
|
||||
}
|
||||
Value::Sequence(ref vs) => {
|
||||
|
|
|
@ -4,6 +4,7 @@ pub mod decoder;
|
|||
pub mod encoder;
|
||||
pub mod reader;
|
||||
pub mod ser;
|
||||
pub mod signed_integer;
|
||||
pub mod value;
|
||||
pub mod writer;
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ use std::convert::TryInto;
|
|||
use std::io::{Read, Error};
|
||||
use std::marker::PhantomData;
|
||||
use super::constants::{Op, InvalidOp, AtomMinor, CompoundMinor};
|
||||
use super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set};
|
||||
use super::signed_integer::SignedInteger;
|
||||
use super::value::{Value, NestedValue, IOValue, FALSE, TRUE, Map, Set, Record};
|
||||
use crate::error::{self, ExpectedKind, Received, is_eof_io_error, io_eof, io_syntax_error};
|
||||
|
||||
pub type IOResult<T> = std::result::Result<T, Error>;
|
||||
|
@ -138,6 +139,8 @@ pub trait Reader<'de> {
|
|||
fn next_u32(&mut self) -> ReaderResult<u32> { self.demand_next(false)?.value().to_u32() }
|
||||
fn next_i64(&mut self) -> ReaderResult<i64> { self.demand_next(false)?.value().to_i64() }
|
||||
fn next_u64(&mut self) -> ReaderResult<u64> { self.demand_next(false)?.value().to_u64() }
|
||||
fn next_i128(&mut self) -> ReaderResult<i128> { self.demand_next(false)?.value().to_i128() }
|
||||
fn next_u128(&mut self) -> ReaderResult<u128> { self.demand_next(false)?.value().to_u128() }
|
||||
fn next_float(&mut self) -> ReaderResult<f32> { self.demand_next(false)?.value().to_float() }
|
||||
fn next_double(&mut self) -> ReaderResult<f64> { self.demand_next(false)?.value().to_double() }
|
||||
fn next_char(&mut self) -> ReaderResult<char> { self.demand_next(false)?.value().to_char() }
|
||||
|
@ -169,7 +172,7 @@ pub trait Reader<'de> {
|
|||
}
|
||||
}
|
||||
|
||||
fn open_simple_record(&mut self, name: &'static str, arity: Option<usize>) ->
|
||||
fn open_simple_record(&mut self, name: &str, arity: Option<usize>) ->
|
||||
ReaderResult<CompoundBody>
|
||||
where
|
||||
Self: Sized
|
||||
|
@ -179,7 +182,7 @@ pub trait Reader<'de> {
|
|||
if label == name {
|
||||
Ok(compound_body)
|
||||
} else {
|
||||
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name, arity),
|
||||
Err(error::Error::Expected(ExpectedKind::SimpleRecord(name.to_owned(), arity),
|
||||
Received::ReceivedRecordWithLabel(label.to_owned())))
|
||||
}
|
||||
}
|
||||
|
@ -354,6 +357,10 @@ pub fn from_read<'de, 'a, IOR: std::io::Read>(read: &'a mut IOR) ->
|
|||
BinaryReader::new(IOBinarySource::new(read))
|
||||
}
|
||||
|
||||
fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
|
||||
error::Error::NumberOutOfRange(i.into())
|
||||
}
|
||||
|
||||
impl<'de, S: BinarySource<'de>> BinaryReader<'de, S> {
|
||||
pub fn new(source: S) -> Self {
|
||||
BinaryReader { source, phantom: PhantomData }
|
||||
|
@ -462,97 +469,94 @@ impl<'de, S: BinarySource<'de>> BinaryReader<'de, S> {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_number_format_b(&mut self, count: usize) -> IOResult<SignedInteger> {
|
||||
if count == 0 {
|
||||
return Ok(SignedInteger::from(0 as i128));
|
||||
}
|
||||
|
||||
if count > 16 {
|
||||
let bs = self.readbytes(count)?;
|
||||
if (bs[0] & 0x80) == 0 {
|
||||
// Positive or zero.
|
||||
let mut i = 0;
|
||||
while i < count && bs[i] == 0 { i = i + 1; }
|
||||
if count - i <= 16 {
|
||||
Ok(SignedInteger::from(u128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap())))
|
||||
} else {
|
||||
Ok(SignedInteger::from(Cow::Owned(BigInt::from_bytes_be(num::bigint::Sign::Plus, &bs[i..]))))
|
||||
}
|
||||
} else {
|
||||
// Negative.
|
||||
let mut i = 0;
|
||||
while i < count && bs[i] == 0xff { i = i + 1; }
|
||||
if count - i <= 16 {
|
||||
Ok(SignedInteger::from(i128::from_be_bytes(bs[bs.len() - 16..].try_into().unwrap())))
|
||||
} else {
|
||||
Ok(SignedInteger::from(Cow::Owned(BigInt::from_signed_bytes_be(&bs))))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let first_byte = self.read()?;
|
||||
let prefix_byte = if (first_byte & 0x80) == 0 { 0x00 } else { 0xff };
|
||||
let mut bs = [prefix_byte; 16];
|
||||
bs[16 - count] = first_byte;
|
||||
self.readbytes_into(&mut bs[16 - (count - 1)..])?;
|
||||
Ok(SignedInteger::from(i128::from_be_bytes(bs)))
|
||||
}
|
||||
}
|
||||
|
||||
fn next_unsigned<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
|
||||
where
|
||||
F: FnOnce(u64) -> Option<T>
|
||||
F: FnOnce(u128) -> Option<T>
|
||||
{
|
||||
match self.peek_next_nonannotation_op()? {
|
||||
(Op::Misc(3), arg) => {
|
||||
self.skip()?;
|
||||
if arg > 12 {
|
||||
Err(error::Error::NumberOutOfRange(decodeint(&[((arg as i8) - 16) as u8])))
|
||||
Err(out_of_range((arg as i8) - 16))
|
||||
} else {
|
||||
f(arg as u64).ok_or_else(|| error::Error::NumberOutOfRange(decodeint(&[arg])))
|
||||
f(arg as u128).ok_or_else(|| out_of_range(arg))
|
||||
}
|
||||
}
|
||||
(Op::Atom(AtomMinor::SignedInteger), arg) => {
|
||||
self.skip()?;
|
||||
let mut count = self.wirelength(arg)?;
|
||||
if count == 0 {
|
||||
return f(0).ok_or_else(|| error::Error::NumberOutOfRange(BigInt::from(0)));
|
||||
}
|
||||
if count > 8 {
|
||||
let prefix = self.readbytes(count - 8)?;
|
||||
if !(&prefix).iter().all(|b| *b == 0x00) {
|
||||
let mut total = prefix.into_owned();
|
||||
total.extend_from_slice(&self.readbytes(8)?);
|
||||
return Err(error::Error::NumberOutOfRange(decodeint(&total)));
|
||||
}
|
||||
count = 8;
|
||||
} else {
|
||||
if (self.peek()? & 0x80) != 0 {
|
||||
return Err(error::Error::NumberOutOfRange(decodeint(&self.readbytes(count)?)))
|
||||
}
|
||||
}
|
||||
let mut bs = [0; 8];
|
||||
self.readbytes_into(&mut bs[8 - count..])?;
|
||||
f(u64::from_be_bytes(bs))
|
||||
.ok_or_else(|| error::Error::NumberOutOfRange(decodeint(&bs)))
|
||||
let count = self.wirelength(arg)?;
|
||||
let n = &self.read_number_format_b(count)?;
|
||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||
f(i).ok_or_else(|| out_of_range(i))
|
||||
}
|
||||
_ => {
|
||||
let i_value = self.demand_next(false)?;
|
||||
let i = i_value.value().to_signedinteger()?;
|
||||
let n = i.to_u64().ok_or_else(|| error::Error::NumberOutOfRange(i.clone()))?;
|
||||
f(n).ok_or_else(|| error::Error::NumberOutOfRange(i.clone()))
|
||||
let n_value = self.demand_next(false)?;
|
||||
let n = n_value.value().to_signedinteger()?;
|
||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||
f(i).ok_or_else(|| out_of_range(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next_signed<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
|
||||
where
|
||||
F: FnOnce(i64) -> Option<T>
|
||||
F: FnOnce(i128) -> Option<T>
|
||||
{
|
||||
match self.peek_next_nonannotation_op()? {
|
||||
(Op::Misc(3), arg) => {
|
||||
self.skip()?;
|
||||
let n = arg as i64;
|
||||
let n = arg as i128;
|
||||
let n = if n > 12 { n - 16 } else { n };
|
||||
f(n).ok_or_else(|| error::Error::NumberOutOfRange(decodeint(&[n as u8])))
|
||||
f(n).ok_or_else(|| out_of_range(n))
|
||||
}
|
||||
(Op::Atom(AtomMinor::SignedInteger), arg) => {
|
||||
self.skip()?;
|
||||
let mut count = self.wirelength(arg)?;
|
||||
if count == 0 {
|
||||
return f(0).ok_or_else(|| error::Error::NumberOutOfRange(BigInt::from(0)));
|
||||
}
|
||||
let fill_byte = if count > 8 {
|
||||
let prefix = self.readbytes(count - 8)?;
|
||||
let fill_byte = if (prefix[0] & 0x80) == 0 { 0x00 } else { 0xff };
|
||||
if !(&prefix).iter().all(|b| *b == fill_byte) {
|
||||
let mut total = prefix.into_owned();
|
||||
total.extend_from_slice(&self.readbytes(8)?);
|
||||
return Err(error::Error::NumberOutOfRange(decodeint(&total)));
|
||||
}
|
||||
count = 8;
|
||||
if (self.peek()? & 0x80) != (fill_byte & 0x80) {
|
||||
let mut total = vec![fill_byte];
|
||||
total.extend_from_slice(&self.readbytes(8)?);
|
||||
return Err(error::Error::NumberOutOfRange(decodeint(&total)));
|
||||
}
|
||||
fill_byte
|
||||
} else {
|
||||
if (self.peek()? & 0x80) == 0 { 0x00 } else { 0xff }
|
||||
};
|
||||
let mut bs = [fill_byte; 8];
|
||||
self.readbytes_into(&mut bs[8 - count..])?;
|
||||
f(i64::from_be_bytes(bs))
|
||||
.ok_or_else(|| error::Error::NumberOutOfRange(decodeint(&bs)))
|
||||
let count = self.wirelength(arg)?;
|
||||
let n = &self.read_number_format_b(count)?;
|
||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||
f(i).ok_or_else(|| out_of_range(i))
|
||||
}
|
||||
_ => {
|
||||
let i_value = self.demand_next(false)?;
|
||||
let i = i_value.value().to_signedinteger()?;
|
||||
let n = i.to_i64().ok_or_else(|| error::Error::NumberOutOfRange(i.clone()))?;
|
||||
f(n).ok_or_else(|| error::Error::NumberOutOfRange(i.clone()))
|
||||
let n_value = self.demand_next(false)?;
|
||||
let n = n_value.value().to_signedinteger()?;
|
||||
let i = n.try_into().or_else(|_| Err(out_of_range(n)))?;
|
||||
f(i).ok_or_else(|| out_of_range(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -612,6 +616,11 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
|
|||
Cow::Owned(Value::from(n).wrap())
|
||||
}
|
||||
(Op::Misc(_), _) => unreachable!(),
|
||||
(Op::Atom(AtomMinor::SignedInteger), arg) => {
|
||||
let count = self.wirelength(arg)?;
|
||||
let n = self.read_number_format_b(count)?;
|
||||
Cow::Owned(Value::SignedInteger(n).wrap())
|
||||
}
|
||||
(Op::Atom(minor), arg) => {
|
||||
let count = self.wirelength(arg)?;
|
||||
Cow::Owned(decodebinary(minor, self.readbytes(count)?)?)
|
||||
|
@ -697,15 +706,17 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for BinaryReader<'de, S> {
|
|||
}
|
||||
}
|
||||
|
||||
fn next_i8(&mut self) -> ReaderResult<i8> { self.next_signed(|n| n.to_i8()) }
|
||||
fn next_i16(&mut self) -> ReaderResult<i16> { self.next_signed(|n| n.to_i16()) }
|
||||
fn next_i32(&mut self) -> ReaderResult<i32> { self.next_signed(|n| n.to_i32()) }
|
||||
fn next_i64(&mut self) -> ReaderResult<i64> { self.next_signed(|n| Some(n)) }
|
||||
fn next_i8(&mut self) -> ReaderResult<i8> { self.next_signed(|n| n.to_i8()) }
|
||||
fn next_i16(&mut self) -> ReaderResult<i16> { self.next_signed(|n| n.to_i16()) }
|
||||
fn next_i32(&mut self) -> ReaderResult<i32> { self.next_signed(|n| n.to_i32()) }
|
||||
fn next_i64(&mut self) -> ReaderResult<i64> { self.next_signed(|n| n.to_i64()) }
|
||||
fn next_i128(&mut self) -> ReaderResult<i128> { self.next_signed(|n| n.to_i128()) }
|
||||
|
||||
fn next_u8(&mut self) -> ReaderResult<u8> { self.next_unsigned(|n| n.to_u8()) }
|
||||
fn next_u16(&mut self) -> ReaderResult<u16> { self.next_unsigned(|n| n.to_u16()) }
|
||||
fn next_u32(&mut self) -> ReaderResult<u32> { self.next_unsigned(|n| n.to_u32()) }
|
||||
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_unsigned(|n| Some(n)) }
|
||||
fn next_u8(&mut self) -> ReaderResult<u8> { self.next_unsigned(|n| n.to_u8()) }
|
||||
fn next_u16(&mut self) -> ReaderResult<u16> { self.next_unsigned(|n| n.to_u16()) }
|
||||
fn next_u32(&mut self) -> ReaderResult<u32> { self.next_unsigned(|n| n.to_u32()) }
|
||||
fn next_u64(&mut self) -> ReaderResult<u64> { self.next_unsigned(|n| n.to_u64()) }
|
||||
fn next_u128(&mut self) -> ReaderResult<u128> { self.next_unsigned(|n| n.to_u128()) }
|
||||
|
||||
fn next_float(&mut self) -> ReaderResult<f32> {
|
||||
match self.peek_next_nonannotation_op()? {
|
||||
|
@ -793,10 +804,6 @@ pub fn decodeop(b: u8) -> IOResult<(Op, u8)> {
|
|||
Ok((Op::try_from(b >> 4)?, b & 15))
|
||||
}
|
||||
|
||||
pub fn decodeint(bs: &[u8]) -> BigInt {
|
||||
BigInt::from_signed_bytes_be(bs)
|
||||
}
|
||||
|
||||
pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
|
||||
match cow {
|
||||
Cow::Borrowed(bs) =>
|
||||
|
@ -808,7 +815,7 @@ pub fn decodestr<'de>(cow: Cow<'de, [u8]>) -> IOResult<Cow<'de, str>> {
|
|||
|
||||
pub fn decodebinary<'de>(minor: AtomMinor, bs: Cow<'de, [u8]>) -> IOResult<IOValue> {
|
||||
Ok(match minor {
|
||||
AtomMinor::SignedInteger => Value::from(decodeint(&bs)).wrap(),
|
||||
AtomMinor::SignedInteger => Value::from(&BigInt::from_signed_bytes_be(&bs)).wrap(),
|
||||
AtomMinor::String => Value::String(decodestr(bs)?.into_owned()).wrap(),
|
||||
AtomMinor::ByteString => Value::ByteString(bs.into_owned()).wrap(),
|
||||
AtomMinor::Symbol => Value::symbol(&decodestr(bs)?).wrap(),
|
||||
|
@ -822,15 +829,14 @@ pub fn decodecompound<'de, I: Iterator<Item = IOResult<Cow<'de, IOValue>>>>(
|
|||
IOResult<IOValue>
|
||||
{
|
||||
match minor {
|
||||
CompoundMinor::Record =>
|
||||
match iter.next() {
|
||||
None => Err(io_syntax_error("Too few elements in encoded record")),
|
||||
Some(labelres) => {
|
||||
let label = labelres?.into_owned();
|
||||
let fields = iter.map(|r| r.map(|c| c.into_owned())).collect::<IOResult<Vec<IOValue>>>()?;
|
||||
Ok(Value::record(label, fields).wrap())
|
||||
}
|
||||
CompoundMinor::Record => {
|
||||
let vs = iter.map(|r| r.map(|c| c.into_owned())).collect::<IOResult<Vec<IOValue>>>()?;
|
||||
if vs.len() < 1 {
|
||||
Err(io_syntax_error("Too few elements in encoded record"))
|
||||
} else {
|
||||
Ok(Value::Record(Record(vs)).wrap())
|
||||
}
|
||||
}
|
||||
CompoundMinor::Sequence => {
|
||||
let vs = iter.map(|r| r.map(|c| c.into_owned())).collect::<IOResult<Vec<IOValue>>>()?;
|
||||
Ok(Value::Sequence(vs).wrap())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::value::{Value, Map, IOValue};
|
||||
use crate::value::{Value, value::Record, Map, IOValue};
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -25,8 +25,7 @@ pub struct SerializeDictionary {
|
|||
}
|
||||
|
||||
pub struct SerializeRecord {
|
||||
name: &'static str,
|
||||
vec: Vec<IOValue>,
|
||||
r: Record<IOValue>,
|
||||
}
|
||||
|
||||
pub struct SerializeSequence {
|
||||
|
@ -89,7 +88,7 @@ impl serde::Serializer for Serializer {
|
|||
}
|
||||
|
||||
fn serialize_char(self, v: char) -> Result<Self::Ok> {
|
||||
Ok(Value::simple_record("UnicodeScalar", vec![Value::from(v as u32).wrap()]).wrap())
|
||||
Ok(Value::simple_record1("UnicodeScalar", Value::from(v as u32).wrap()).wrap())
|
||||
}
|
||||
|
||||
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
|
||||
|
@ -101,19 +100,19 @@ impl serde::Serializer for Serializer {
|
|||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok> {
|
||||
Ok(Value::simple_record("None", vec![]).wrap())
|
||||
Ok(Value::simple_record0("None").wrap())
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok> where T: Serialize {
|
||||
Ok(Value::simple_record("Some", vec![to_value(v)]).wrap())
|
||||
Ok(Value::simple_record1("Some", to_value(v)).wrap())
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok> {
|
||||
Ok(Value::simple_record("tuple", vec![]).wrap())
|
||||
Ok(Value::simple_record0("tuple").wrap())
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> {
|
||||
Ok(Value::simple_record(name, vec![]).wrap())
|
||||
Ok(Value::simple_record0(name).wrap())
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(self,
|
||||
|
@ -122,7 +121,7 @@ impl serde::Serializer for Serializer {
|
|||
variant_name: &'static str) ->
|
||||
Result<Self::Ok>
|
||||
{
|
||||
Ok(Value::simple_record(variant_name, vec![]).wrap())
|
||||
Ok(Value::simple_record0(variant_name).wrap())
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) ->
|
||||
|
@ -132,7 +131,7 @@ impl serde::Serializer for Serializer {
|
|||
Some(v) => Ok(v),
|
||||
None => {
|
||||
// TODO: This is apparently discouraged, and we should apparently just serialize `value`?
|
||||
Ok(Value::simple_record(name, vec![to_value(value)]).wrap())
|
||||
Ok(Value::simple_record1(name, to_value(value)).wrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +143,7 @@ impl serde::Serializer for Serializer {
|
|||
value: &T) ->
|
||||
Result<Self::Ok> where T: Serialize
|
||||
{
|
||||
Ok(Value::simple_record(variant_name, vec![to_value(value)]).wrap())
|
||||
Ok(Value::simple_record1(variant_name, to_value(value)).wrap())
|
||||
}
|
||||
|
||||
fn serialize_seq(self, count: Option<usize>) -> Result<Self::SerializeSeq> {
|
||||
|
@ -153,13 +152,13 @@ impl serde::Serializer for Serializer {
|
|||
}
|
||||
|
||||
fn serialize_tuple(self, count: usize) -> Result<Self::SerializeTuple> {
|
||||
Ok(SerializeRecord { name: "tuple", vec: Vec::with_capacity(count) })
|
||||
Ok(SerializeRecord { r: Value::simple_record("tuple", count) })
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(self, name: &'static str, count: usize) ->
|
||||
Result<Self::SerializeTupleStruct>
|
||||
{
|
||||
Ok(SerializeRecord { name, vec: Vec::with_capacity(count) })
|
||||
Ok(SerializeRecord { r: Value::simple_record(name, count) })
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(self,
|
||||
|
@ -169,7 +168,7 @@ impl serde::Serializer for Serializer {
|
|||
count: usize) ->
|
||||
Result<Self::SerializeTupleVariant>
|
||||
{
|
||||
Ok(SerializeRecord { name: variant_name, vec: Vec::with_capacity(count) })
|
||||
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) })
|
||||
}
|
||||
|
||||
fn serialize_map(self, _count: Option<usize>) -> Result<Self::SerializeMap> {
|
||||
|
@ -177,7 +176,7 @@ impl serde::Serializer for Serializer {
|
|||
}
|
||||
|
||||
fn serialize_struct(self, name: &'static str, count: usize) -> Result<Self::SerializeStruct> {
|
||||
Ok(SerializeRecord { name, vec: Vec::with_capacity(count) })
|
||||
Ok(SerializeRecord { r: Value::simple_record(name, count) })
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(self,
|
||||
|
@ -187,7 +186,7 @@ impl serde::Serializer for Serializer {
|
|||
count: usize) ->
|
||||
Result<Self::SerializeStructVariant>
|
||||
{
|
||||
Ok(SerializeRecord { name: variant_name, vec: Vec::with_capacity(count) })
|
||||
Ok(SerializeRecord { r: Value::simple_record(variant_name, count) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,12 +212,12 @@ impl serde::ser::SerializeMap for SerializeDictionary {
|
|||
|
||||
impl SerializeRecord {
|
||||
fn push(&mut self, value: IOValue) -> Result<()> {
|
||||
self.vec.push(value);
|
||||
self.r.fields_vec_mut().push(value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn finish(self) -> Result<IOValue> {
|
||||
Ok(Value::simple_record(self.name, self.vec).wrap())
|
||||
Ok(self.r.finish().wrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
use num::bigint::BigInt;
|
||||
use num::traits::cast::ToPrimitive;
|
||||
use num::traits::sign::Signed;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::{Ord, Ordering, PartialOrd};
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
|
||||
// Invariant: if I128 can be used, it will be; otherwise, if U128 can
|
||||
// be used, it will be; otherwise, Big will be used.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum SignedIntegerRepr {
|
||||
I128(i128),
|
||||
U128(u128),
|
||||
Big(Box<BigInt>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct SignedInteger(SignedIntegerRepr);
|
||||
|
||||
impl fmt::Display for SignedInteger {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
match self.repr() {
|
||||
SignedIntegerRepr::I128(i) => i.fmt(f),
|
||||
SignedIntegerRepr::U128(u) => u.fmt(f),
|
||||
SignedIntegerRepr::Big(n) => n.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for SignedInteger {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
match self.repr() {
|
||||
SignedIntegerRepr::I128(i1) => match other.repr() {
|
||||
SignedIntegerRepr::I128(i2) => i1.cmp(i2),
|
||||
SignedIntegerRepr::U128(_) => if *i1 < 0 { Ordering::Less } else { Ordering::Greater },
|
||||
SignedIntegerRepr::Big(n) => if n.is_negative() { Ordering::Less } else { Ordering::Greater },
|
||||
},
|
||||
SignedIntegerRepr::U128(u1) => match other.repr() {
|
||||
SignedIntegerRepr::I128(_) => Ordering::Greater,
|
||||
SignedIntegerRepr::U128(u2) => u1.cmp(u2),
|
||||
SignedIntegerRepr::Big(n) => if n.is_positive() { Ordering::Less } else { Ordering::Greater },
|
||||
},
|
||||
SignedIntegerRepr::Big(n1) => match other.repr() {
|
||||
SignedIntegerRepr::I128(_) |
|
||||
SignedIntegerRepr::U128(_) => if n1.is_negative() { Ordering::Less } else { Ordering::Greater },
|
||||
SignedIntegerRepr::Big(n2) => n1.cmp(n2),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for SignedInteger {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl SignedInteger {
|
||||
pub fn repr(&self) -> &SignedIntegerRepr {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn is_i(&self) -> bool {
|
||||
match self.repr() {
|
||||
SignedIntegerRepr::I128(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_u(&self) -> bool {
|
||||
match self.0 {
|
||||
SignedIntegerRepr::U128(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_big(&self) -> bool {
|
||||
match self.0 {
|
||||
SignedIntegerRepr::Big(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i128> for SignedInteger {
|
||||
fn from(v: i128) -> Self {
|
||||
SignedInteger(SignedIntegerRepr::I128(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for SignedInteger {
|
||||
fn from(v: u128) -> Self {
|
||||
if let Ok(w) = v.try_into() {
|
||||
SignedInteger(SignedIntegerRepr::I128(w))
|
||||
} else {
|
||||
SignedInteger(SignedIntegerRepr::U128(v))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Cow<'a, BigInt>> for SignedInteger {
|
||||
fn from(v: Cow<'a, BigInt>) -> Self {
|
||||
if let Some(w) = v.to_i128() {
|
||||
SignedInteger(SignedIntegerRepr::I128(w))
|
||||
} else if let Some(w) = v.to_u128() {
|
||||
SignedInteger(SignedIntegerRepr::U128(w))
|
||||
} else {
|
||||
SignedInteger(SignedIntegerRepr::Big(Box::new(v.into_owned())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&SignedInteger> for i128 {
|
||||
type Error = ();
|
||||
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
|
||||
match v.repr() {
|
||||
SignedIntegerRepr::I128(i) => Ok(*i),
|
||||
SignedIntegerRepr::U128(_) => Err(()),
|
||||
SignedIntegerRepr::Big(_) => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&SignedInteger> for u128 {
|
||||
type Error = ();
|
||||
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
|
||||
match v.repr() {
|
||||
SignedIntegerRepr::I128(i) => i.to_u128().ok_or(()),
|
||||
SignedIntegerRepr::U128(u) => Ok(*u),
|
||||
SignedIntegerRepr::Big(_) => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SignedInteger> for Cow<'a, BigInt> {
|
||||
fn from(v: &'a SignedInteger) -> Self {
|
||||
match v.repr() {
|
||||
SignedIntegerRepr::I128(i) => Cow::Owned(BigInt::from(*i)),
|
||||
SignedIntegerRepr::U128(u) => Cow::Owned(BigInt::from(*u)),
|
||||
SignedIntegerRepr::Big(n) => Cow::Borrowed(n),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SignedInteger> for BigInt {
|
||||
fn from(v: &'a SignedInteger) -> Self {
|
||||
match v.repr() {
|
||||
SignedIntegerRepr::I128(i) => BigInt::from(*i),
|
||||
SignedIntegerRepr::U128(u) => BigInt::from(*u),
|
||||
SignedIntegerRepr::Big(n) => *n.clone(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
use num::bigint::BigInt;
|
||||
use num::traits::cast::ToPrimitive;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Index;
|
||||
|
@ -12,6 +14,7 @@ use std::vec::Vec;
|
|||
pub use std::collections::BTreeSet as Set;
|
||||
pub use std::collections::BTreeMap as Map;
|
||||
|
||||
use super::signed_integer::SignedInteger;
|
||||
use crate::error::{Error, ExpectedKind, Received};
|
||||
|
||||
pub trait Domain: Sized + Debug + Clone + Eq + Hash + Ord {
|
||||
|
@ -23,14 +26,9 @@ pub trait Domain: Sized + Debug + Clone + Eq + Hash + Ord {
|
|||
}
|
||||
|
||||
pub trait NestedValue<D: Domain>: Sized + Debug + Clone + Eq + Hash + Ord {
|
||||
type BoxType: Sized + Debug + Clone + Eq + Hash + Ord;
|
||||
|
||||
fn wrap(v: Value<Self, D>) -> Self;
|
||||
fn wrap_ann(anns: Vec<Self>, v: Value<Self, D>) -> Self;
|
||||
|
||||
fn boxwrap(self) -> Self::BoxType;
|
||||
fn boxunwrap(b: &Self::BoxType) -> &Self;
|
||||
|
||||
fn annotations(&self) -> &[Self];
|
||||
fn value(&self) -> &Value<Self, D>;
|
||||
fn pieces(self) -> (Vec<Self>, Value<Self, D>);
|
||||
|
@ -66,11 +64,11 @@ pub enum Value<N, D> where N: NestedValue<D>, D: Domain {
|
|||
Boolean(bool),
|
||||
Float(Float),
|
||||
Double(Double),
|
||||
SignedInteger(BigInt),
|
||||
SignedInteger(SignedInteger),
|
||||
String(String),
|
||||
ByteString(Vec<u8>),
|
||||
Symbol(String),
|
||||
Record(Record<N, D>),
|
||||
Record(Record<N>),
|
||||
Sequence(Vec<N>),
|
||||
Set(Set<N>),
|
||||
Dictionary(Map<N, N>),
|
||||
|
@ -85,8 +83,43 @@ pub struct Float(pub f32);
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct Double(pub f64);
|
||||
|
||||
/// A Record `Value`
|
||||
pub type Record<N, D> = (<N as NestedValue<D>>::BoxType, Vec<N>);
|
||||
/// A Record `Value` -- INVARIANT: length always non-zero
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Record<N>(pub Vec<N>);
|
||||
|
||||
impl<N> Record<N> {
|
||||
pub fn label(&self) -> &N {
|
||||
&self.0[0]
|
||||
}
|
||||
|
||||
pub fn label_mut(&mut self) -> &mut N {
|
||||
&mut self.0[0]
|
||||
}
|
||||
|
||||
pub fn arity(&self) -> usize {
|
||||
self.0.len() - 1
|
||||
}
|
||||
|
||||
pub fn fields(&self) -> &[N] {
|
||||
&self.0[1..]
|
||||
}
|
||||
|
||||
pub fn fields_mut(&mut self) -> &mut [N] {
|
||||
&mut self.0[1..]
|
||||
}
|
||||
|
||||
pub fn fields_vec(&self) -> &Vec<N> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn fields_vec_mut(&mut self) -> &mut Vec<N> {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
pub fn finish<D: Domain>(self) -> Value<N, D> where N: NestedValue<D> {
|
||||
Value::Record(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for Float {
|
||||
fn from(v: f32) -> Self {
|
||||
|
@ -185,9 +218,9 @@ impl<N: NestedValue<D>, D: Domain> From<u32> for Value<N, D> { fn from(v: u32) -
|
|||
impl<N: NestedValue<D>, D: Domain> From<i32> for Value<N, D> { fn from(v: i32) -> Self { Value::from(i128::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<u64> for Value<N, D> { fn from(v: u64) -> Self { Value::from(i128::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<i64> for Value<N, D> { fn from(v: i64) -> Self { Value::from(i128::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<u128> for Value<N, D> { fn from(v: u128) -> Self { Value::SignedInteger(BigInt::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<i128> for Value<N, D> { fn from(v: i128) -> Self { Value::SignedInteger(BigInt::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<BigInt> for Value<N, D> { fn from(v: BigInt) -> Self { Value::SignedInteger(v) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<u128> for Value<N, D> { fn from(v: u128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<i128> for Value<N, D> { fn from(v: i128) -> Self { Value::SignedInteger(SignedInteger::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<&BigInt> for Value<N, D> { fn from(v: &BigInt) -> Self { Value::SignedInteger(SignedInteger::from(Cow::Borrowed(v))) } }
|
||||
|
||||
impl<N: NestedValue<D>, D: Domain> From<&str> for Value<N, D> { fn from(v: &str) -> Self { Value::String(String::from(v)) } }
|
||||
impl<N: NestedValue<D>, D: Domain> From<String> for Value<N, D> { fn from(v: String) -> Self { Value::String(v) } }
|
||||
|
@ -223,10 +256,10 @@ impl<N: NestedValue<D>, D: Domain> Debug for Value<N, D> {
|
|||
write!(f, "{}", v)
|
||||
}
|
||||
}
|
||||
Value::Record((ref l, ref fs)) => {
|
||||
Value::Record(ref r) => {
|
||||
f.write_str("<")?;
|
||||
l.fmt(f)?;
|
||||
for v in fs {
|
||||
r.label().fmt(f)?;
|
||||
for v in r.fields() {
|
||||
f.write_str(" ")?;
|
||||
v.fmt(f)?;
|
||||
}
|
||||
|
@ -330,73 +363,129 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
|||
self.as_signedinteger().is_some()
|
||||
}
|
||||
|
||||
pub fn as_signedinteger(&self) -> Option<&BigInt> {
|
||||
if let Value::SignedInteger(ref i) = *self {
|
||||
Some(i)
|
||||
pub fn as_signedinteger(&self) -> Option<&SignedInteger> {
|
||||
if let Value::SignedInteger(ref n) = *self {
|
||||
Some(n)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_signedinteger_mut(&mut self) -> Option<&mut BigInt> {
|
||||
if let Value::SignedInteger(ref mut i) = *self {
|
||||
Some(i)
|
||||
pub fn as_signedinteger_mut(&mut self) -> Option<&mut SignedInteger> {
|
||||
if let Value::SignedInteger(ref mut n) = *self {
|
||||
Some(n)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_signedinteger(&self) -> Result<&BigInt, Error> {
|
||||
pub fn to_signedinteger(&self) -> Result<&SignedInteger, Error> {
|
||||
self.as_signedinteger().ok_or_else(|| self.expected(ExpectedKind::SignedInteger))
|
||||
}
|
||||
|
||||
pub fn as_u8(&self) -> Option<u8> { self.as_signedinteger().and_then(|i| i.to_u8()) }
|
||||
pub fn as_i8(&self) -> Option<i8> { self.as_signedinteger().and_then(|i| i.to_i8()) }
|
||||
pub fn as_u16(&self) -> Option<u16> { self.as_signedinteger().and_then(|i| i.to_u16()) }
|
||||
pub fn as_i16(&self) -> Option<i16> { self.as_signedinteger().and_then(|i| i.to_i16()) }
|
||||
pub fn as_u32(&self) -> Option<u32> { self.as_signedinteger().and_then(|i| i.to_u32()) }
|
||||
pub fn as_i32(&self) -> Option<i32> { self.as_signedinteger().and_then(|i| i.to_i32()) }
|
||||
pub fn as_u64(&self) -> Option<u64> { self.as_signedinteger().and_then(|i| i.to_u64()) }
|
||||
pub fn as_i64(&self) -> Option<i64> { self.as_signedinteger().and_then(|i| i.to_i64()) }
|
||||
pub fn is_i(&self) -> bool {
|
||||
self.as_i().is_some()
|
||||
}
|
||||
|
||||
pub fn as_i(&self) -> Option<i128> {
|
||||
self.as_signedinteger().and_then(|n| n.try_into().ok())
|
||||
}
|
||||
|
||||
pub fn to_i(&self) -> Result<i128, Error> {
|
||||
self.as_i().ok_or_else(|| self.expected(ExpectedKind::SignedIntegerI128))
|
||||
}
|
||||
|
||||
pub fn is_u(&self) -> bool {
|
||||
self.as_u().is_some()
|
||||
}
|
||||
|
||||
pub fn as_u(&self) -> Option<u128> {
|
||||
self.as_signedinteger().and_then(|n| n.try_into().ok())
|
||||
}
|
||||
|
||||
pub fn to_u(&self) -> Result<u128, Error> {
|
||||
self.as_u().ok_or_else(|| self.expected(ExpectedKind::SignedIntegerU128))
|
||||
}
|
||||
|
||||
pub fn as_u8(&self) -> Option<u8> { self.as_u().and_then(|i| i.to_u8()) }
|
||||
pub fn as_i8(&self) -> Option<i8> { self.as_i().and_then(|i| i.to_i8()) }
|
||||
pub fn as_u16(&self) -> Option<u16> { self.as_u().and_then(|i| i.to_u16()) }
|
||||
pub fn as_i16(&self) -> Option<i16> { self.as_i().and_then(|i| i.to_i16()) }
|
||||
pub fn as_u32(&self) -> Option<u32> { self.as_u().and_then(|i| i.to_u32()) }
|
||||
pub fn as_i32(&self) -> Option<i32> { self.as_i().and_then(|i| i.to_i32()) }
|
||||
pub fn as_u64(&self) -> Option<u64> { self.as_u().and_then(|i| i.to_u64()) }
|
||||
pub fn as_i64(&self) -> Option<i64> { self.as_i().and_then(|i| i.to_i64()) }
|
||||
pub fn as_u128(&self) -> Option<u128> { self.as_u().and_then(|i| i.to_u128()) }
|
||||
pub fn as_i128(&self) -> Option<i128> { self.as_i().and_then(|i| i.to_i128()) }
|
||||
|
||||
pub fn to_i8(&self) -> Result<i8, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_i8().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_u8(&self) -> Result<u8, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_u8().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
}
|
||||
|
||||
pub fn to_u16(&self) -> Result<u16, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_u16().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
match self.as_u() {
|
||||
Some(i) => i.to_u8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_i16(&self) -> Result<i16, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_i16().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i16().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_u32(&self) -> Result<u32, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_u32().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
pub fn to_u16(&self) -> Result<u16, Error> {
|
||||
match self.as_u() {
|
||||
Some(i) => i.to_u16().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_i32(&self) -> Result<i32, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_i32().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i32().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_u64(&self) -> Result<u64, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_u64().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
pub fn to_u32(&self) -> Result<u32, Error> {
|
||||
match self.as_u() {
|
||||
Some(i) => i.to_u32().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_i64(&self) -> Result<i64, Error> {
|
||||
let i = self.to_signedinteger()?;
|
||||
i.to_i64().ok_or_else(|| Error::NumberOutOfRange(i.clone()))
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i64().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_u64(&self) -> Result<u64, Error> {
|
||||
match self.as_u() {
|
||||
Some(i) => i.to_u64().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_i128(&self) -> Result<i128, Error> {
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i128().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_u128(&self) -> Result<u128, Error> {
|
||||
match self.as_u() {
|
||||
Some(i) => i.to_u128().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
None => Err(self.expected(ExpectedKind::SignedInteger)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_char(&self) -> Result<char, Error> {
|
||||
|
@ -481,18 +570,24 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
|||
self.as_symbol().ok_or_else(|| self.expected(ExpectedKind::Symbol))
|
||||
}
|
||||
|
||||
pub fn record(label: N, fields: Vec<N>) -> Value<N, D> {
|
||||
Value::Record((label.boxwrap(), fields))
|
||||
pub fn record(label: N, expected_arity: usize) -> Record<N> {
|
||||
let mut v = Vec::with_capacity(expected_arity + 1);
|
||||
v.push(label);
|
||||
Record(v)
|
||||
}
|
||||
|
||||
pub fn is_record(&self) -> bool {
|
||||
self.as_record(None).is_some()
|
||||
if let Value::Record(_) = *self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_record(&self, arity: Option<usize>) -> Option<&Record<N, D>> {
|
||||
pub fn as_record(&self, arity: Option<usize>) -> Option<&Record<N>> {
|
||||
if let Value::Record(ref r) = *self {
|
||||
match arity {
|
||||
Some(expected) if r.1.len() == expected => Some(r),
|
||||
Some(expected) if r.arity() == expected => Some(r),
|
||||
Some(_other) => None,
|
||||
None => Some(r)
|
||||
}
|
||||
|
@ -501,10 +596,10 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_record_mut(&mut self, arity: Option<usize>) -> Option<&mut Record<N, D>> {
|
||||
pub fn as_record_mut(&mut self, arity: Option<usize>) -> Option<&mut Record<N>> {
|
||||
if let Value::Record(ref mut r) = *self {
|
||||
match arity {
|
||||
Some(expected) if r.1.len() == expected => Some(r),
|
||||
Some(expected) if r.arity() == expected => Some(r),
|
||||
Some(_other) => None,
|
||||
None => Some(r)
|
||||
}
|
||||
|
@ -513,32 +608,42 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N, D>, Error> {
|
||||
pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N>, Error> {
|
||||
self.as_record(arity).ok_or_else(|| self.expected(ExpectedKind::Record(arity)))
|
||||
}
|
||||
|
||||
pub fn simple_record(label: &str, fields: Vec<N>) -> Value<N, D> {
|
||||
Value::record(Value::symbol(label).wrap(), fields)
|
||||
pub fn simple_record(label: &str, expected_arity: usize) -> Record<N> {
|
||||
Self::record(Value::symbol(label).wrap(), expected_arity)
|
||||
}
|
||||
|
||||
pub fn simple_record0(label: &str) -> Value<N, D> {
|
||||
Self::simple_record(label, 0).finish()
|
||||
}
|
||||
|
||||
pub fn simple_record1(label: &str, field: N) -> Value<N, D> {
|
||||
let mut r = Self::simple_record(label, 1);
|
||||
r.fields_vec_mut().push(field);
|
||||
r.finish()
|
||||
}
|
||||
|
||||
pub fn is_simple_record(&self, label: &str, arity: Option<usize>) -> bool {
|
||||
self.as_simple_record(label, arity).is_some()
|
||||
}
|
||||
|
||||
pub fn as_simple_record(&self, label: &str, arity: Option<usize>) -> Option<&Vec<N>> {
|
||||
self.as_record(arity).and_then(|(lp,fs)| {
|
||||
match N::boxunwrap(lp).value() {
|
||||
Value::Symbol(ref s) if s == label => Some(fs),
|
||||
pub fn as_simple_record(&self, label: &str, arity: Option<usize>) -> Option<&[N]> {
|
||||
self.as_record(arity).and_then(|r| {
|
||||
match r.label().value() {
|
||||
Value::Symbol(ref s) if s == label => Some(r.fields()),
|
||||
_ => None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_simple_record(&self, label: &'static str, arity: Option<usize>) ->
|
||||
Result<&Vec<N>, Error>
|
||||
pub fn to_simple_record(&self, label: &str, arity: Option<usize>) ->
|
||||
Result<&[N], Error>
|
||||
{
|
||||
self.as_simple_record(label, arity)
|
||||
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label, arity)))
|
||||
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity)))
|
||||
}
|
||||
|
||||
pub fn to_option(&self) -> Result<Option<&N>, Error> {
|
||||
|
@ -631,13 +736,12 @@ impl<N: NestedValue<D>, D: Domain> Value<N, D> {
|
|||
Value::Boolean(b) => Value::Boolean(*b),
|
||||
Value::Float(f) => Value::Float(f.clone()),
|
||||
Value::Double(d) => Value::Double(d.clone()),
|
||||
Value::SignedInteger(i) => Value::SignedInteger(i.clone()),
|
||||
Value::SignedInteger(ref n) => Value::SignedInteger(n.clone()),
|
||||
Value::String(ref s) => Value::String(s.clone()),
|
||||
Value::ByteString(ref v) => Value::ByteString(v.clone()),
|
||||
Value::Symbol(ref v) => Value::Symbol(v.clone()),
|
||||
Value::Record((ref l, ref fs)) =>
|
||||
Value::Record((N::boxunwrap(l).copy_via::<M,E,F>(f).boxwrap(),
|
||||
fs.iter().map(|a| a.copy_via(f)).collect())),
|
||||
Value::Record(ref r) =>
|
||||
Value::Record(Record(r.fields_vec().iter().map(|a| a.copy_via(f)).collect())),
|
||||
Value::Sequence(ref v) => Value::Sequence(v.iter().map(|a| a.copy_via(f)).collect()),
|
||||
Value::Set(ref v) => Value::Set(v.iter().map(|a| a.copy_via(f)).collect()),
|
||||
Value::Dictionary(ref v) =>
|
||||
|
@ -745,8 +849,6 @@ impl<D: Domain> PlainValue<D> {
|
|||
}
|
||||
|
||||
impl<D: Domain> NestedValue<D> for PlainValue<D> {
|
||||
type BoxType = Box<Self>;
|
||||
|
||||
fn wrap(v: Value<Self, D>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
}
|
||||
|
@ -755,14 +857,6 @@ impl<D: Domain> NestedValue<D> for PlainValue<D> {
|
|||
PlainValue(AnnotatedValue(anns, v))
|
||||
}
|
||||
|
||||
fn boxwrap(self) -> Self::BoxType {
|
||||
Box::new(self)
|
||||
}
|
||||
|
||||
fn boxunwrap(b: &Self::BoxType) -> &Self {
|
||||
&**b
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
&(self.0).0
|
||||
}
|
||||
|
@ -807,8 +901,6 @@ use std::rc::Rc;
|
|||
pub struct RcValue<D: Domain>(Rc<AnnotatedValue<RcValue<D>, D>>);
|
||||
|
||||
impl<D: Domain> NestedValue<D> for RcValue<D> {
|
||||
type BoxType = Self;
|
||||
|
||||
fn wrap(v: Value<Self, D>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
}
|
||||
|
@ -817,14 +909,6 @@ impl<D: Domain> NestedValue<D> for RcValue<D> {
|
|||
RcValue(Rc::new(AnnotatedValue(anns, v)))
|
||||
}
|
||||
|
||||
fn boxwrap(self) -> Self::BoxType {
|
||||
self
|
||||
}
|
||||
|
||||
fn boxunwrap(b: &Self::BoxType) -> &Self {
|
||||
b
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
&(self.0).0
|
||||
}
|
||||
|
@ -871,8 +955,6 @@ use std::sync::Arc;
|
|||
pub struct ArcValue<D: Domain>(Arc<AnnotatedValue<ArcValue<D>, D>>);
|
||||
|
||||
impl<D: Domain> NestedValue<D> for ArcValue<D> {
|
||||
type BoxType = Self;
|
||||
|
||||
fn wrap(v: Value<Self, D>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
}
|
||||
|
@ -881,14 +963,6 @@ impl<D: Domain> NestedValue<D> for ArcValue<D> {
|
|||
ArcValue(Arc::new(AnnotatedValue(anns, v)))
|
||||
}
|
||||
|
||||
fn boxwrap(self) -> Self::BoxType {
|
||||
self
|
||||
}
|
||||
|
||||
fn boxunwrap(b: &Self::BoxType) -> &Self {
|
||||
b
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
&(self.0).0
|
||||
}
|
||||
|
@ -944,8 +1018,6 @@ lazy_static! {
|
|||
}
|
||||
|
||||
impl NestedValue<NullDomain> for IOValue {
|
||||
type BoxType = Self;
|
||||
|
||||
fn wrap(v: Value<Self, NullDomain>) -> Self {
|
||||
Self::wrap_ann(Vec::new(), v)
|
||||
}
|
||||
|
@ -954,14 +1026,6 @@ impl NestedValue<NullDomain> for IOValue {
|
|||
IOValue(Arc::new(AnnotatedValue(anns, v)))
|
||||
}
|
||||
|
||||
fn boxwrap(self) -> Self::BoxType {
|
||||
self
|
||||
}
|
||||
|
||||
fn boxunwrap(b: &Self::BoxType) -> &Self {
|
||||
b
|
||||
}
|
||||
|
||||
fn annotations(&self) -> &[Self] {
|
||||
&(self.0).0
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use num;
|
||||
use num::bigint::BigInt;
|
||||
use num::cast::ToPrimitive;
|
||||
use std::convert::TryInto;
|
||||
|
@ -23,6 +24,8 @@ pub trait Writer {
|
|||
fn write_u32(&mut self, v: u32) -> Result;
|
||||
fn write_i64(&mut self, v: i64) -> Result;
|
||||
fn write_u64(&mut self, v: u64) -> Result;
|
||||
fn write_i128(&mut self, v: i128) -> Result;
|
||||
fn write_u128(&mut self, v: u128) -> Result;
|
||||
fn write_int(&mut self, v: &BigInt) -> Result;
|
||||
|
||||
fn write_string(&mut self, v: &str) -> Result;
|
||||
|
@ -80,6 +83,13 @@ pub fn write_atom<W: std::io::Write>(w: &mut W, minor: AtomMinor, bs: &[u8]) ->
|
|||
w.write_all(bs)
|
||||
}
|
||||
|
||||
macro_rules! fits_in_bytes {
|
||||
($v:ident, $limit:literal) => ({
|
||||
let bits = $limit * 8 - 1;
|
||||
$v >= -(2 << bits) && $v < (2 << bits)
|
||||
})
|
||||
}
|
||||
|
||||
impl<W: std::io::Write> Writer for W {
|
||||
fn write_annotation_prefix(&mut self) -> Result {
|
||||
write_header(self, Op::Misc(0), 5)
|
||||
|
@ -126,7 +136,7 @@ impl<W: std::io::Write> Writer for W {
|
|||
|
||||
fn write_i32(&mut self, v: i32) -> Result {
|
||||
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
||||
if v >= -(2 << 23) && v < (2 << 23) {
|
||||
if fits_in_bytes!(v, 3) {
|
||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
|
@ -148,14 +158,14 @@ impl<W: std::io::Write> Writer for W {
|
|||
|
||||
fn write_i64(&mut self, v: i64) -> Result {
|
||||
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
||||
if v >= -(2 << 39) && v < (2 << 39) {
|
||||
if fits_in_bytes!(v, 5) {
|
||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
(v >> 16) as u8,
|
||||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
}
|
||||
if v >= -(2 << 47) && v < (2 << 47) {
|
||||
if fits_in_bytes!(v, 6) {
|
||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
(v >> 24) as u8,
|
||||
|
@ -163,7 +173,7 @@ impl<W: std::io::Write> Writer for W {
|
|||
(v >> 8) as u8,
|
||||
(v & 255) as u8]);
|
||||
}
|
||||
if v >= -(2 << 55) && v < (2 << 55) {
|
||||
if fits_in_bytes!(v, 7) {
|
||||
return write_atom(self, AtomMinor::SignedInteger, &[(v >> 48) as u8,
|
||||
(v >> 40) as u8,
|
||||
(v >> 32) as u8,
|
||||
|
@ -195,6 +205,27 @@ impl<W: std::io::Write> Writer for W {
|
|||
(v & 255) as u8]);
|
||||
}
|
||||
|
||||
fn write_i128(&mut self, v: i128) -> Result {
|
||||
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
||||
let bs: [u8; 16] = v.to_be_bytes();
|
||||
if fits_in_bytes!(v, 9) { return write_atom(self, AtomMinor::SignedInteger, &bs[7..]); }
|
||||
if fits_in_bytes!(v, 10) { return write_atom(self, AtomMinor::SignedInteger, &bs[6..]); }
|
||||
if fits_in_bytes!(v, 11) { return write_atom(self, AtomMinor::SignedInteger, &bs[5..]); }
|
||||
if fits_in_bytes!(v, 12) { return write_atom(self, AtomMinor::SignedInteger, &bs[4..]); }
|
||||
if fits_in_bytes!(v, 13) { return write_atom(self, AtomMinor::SignedInteger, &bs[3..]); }
|
||||
if fits_in_bytes!(v, 14) { return write_atom(self, AtomMinor::SignedInteger, &bs[2..]); }
|
||||
if fits_in_bytes!(v, 15) { return write_atom(self, AtomMinor::SignedInteger, &bs[1..]); }
|
||||
return write_atom(self, AtomMinor::SignedInteger, &bs);
|
||||
}
|
||||
|
||||
fn write_u128(&mut self, v: u128) -> Result {
|
||||
if let Ok(w) = v.try_into() { return self.write_i128(w) }
|
||||
let bs: [u8; 16] = v.to_be_bytes();
|
||||
write_header(self, Op::Atom(AtomMinor::SignedInteger), bs.len() + 1)?;
|
||||
self.write_all(&[0])?;
|
||||
self.write_all(&bs)
|
||||
}
|
||||
|
||||
fn write_int(&mut self, v: &BigInt) -> Result {
|
||||
match v.to_i8() {
|
||||
Some(n) => self.write_i8(n),
|
||||
|
|
Loading…
Reference in New Issue