forked from syndicate-lang/preserves
Inline the heck out of the binary codec for a ~5% speedup
This commit is contained in:
parent
e31cf739df
commit
e2a4e3d6cb
|
@ -14,14 +14,14 @@ impl<'de> serde::de::Visitor<'de> for IOValueVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn output_value<S: serde::Serializer>(serializer: S, v: IOValue) ->
|
||||
Result<S::Ok, S::Error>
|
||||
{
|
||||
serializer.serialize_newtype_struct(MAGIC, &(Box::into_raw(Box::new(v)) as u64))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn input_value<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<IOValue, D::Error>
|
||||
{
|
||||
deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor)
|
||||
|
|
|
@ -41,21 +41,27 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
for PackedReader<'de, 'src, N, Dec, S>
|
||||
{
|
||||
type Mark = S::Mark;
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
self.source.mark()
|
||||
}
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
self.source.restore(mark)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn skip(&mut self) -> io::Result<()> {
|
||||
self.source.skip()
|
||||
}
|
||||
#[inline(always)]
|
||||
fn peek(&mut self) -> io::Result<u8> {
|
||||
self.source.peek()
|
||||
}
|
||||
#[inline(always)]
|
||||
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
|
||||
self.source.readbytes(count)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
|
||||
self.source.readbytes_into(bs)
|
||||
}
|
||||
|
@ -66,10 +72,12 @@ fn out_of_range<I: Into<BigInt>>(i: I) -> error::Error {
|
|||
}
|
||||
|
||||
impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<'de>> PackedReader<'de, 'src, N, Dec, S> {
|
||||
#[inline(always)]
|
||||
pub fn new(source: &'src mut S, decode_embedded: Dec) -> Self {
|
||||
PackedReader { source, decode_embedded, phantom: PhantomData }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn read(&mut self) -> io::Result<u8> {
|
||||
let v = self.peek()?;
|
||||
self.skip()?;
|
||||
|
@ -83,6 +91,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn varint(&mut self) -> io::Result<usize> {
|
||||
let mut shift = 0;
|
||||
let mut acc: usize = 0;
|
||||
|
@ -94,6 +103,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn peekend(&mut self) -> io::Result<bool> {
|
||||
if self.peek()? == Tag::End.into() {
|
||||
self.skip()?;
|
||||
|
@ -103,6 +113,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn peek_next_nonannotation_tag(&mut self) -> ReaderResult<Tag> {
|
||||
loop {
|
||||
match Tag::try_from(self.peek()?)? {
|
||||
|
@ -137,6 +148,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn read_signed_integer(&mut self, count: usize) -> io::Result<SignedInteger> {
|
||||
if count == 0 {
|
||||
return Ok(SignedInteger::from(0_i128));
|
||||
|
@ -173,6 +185,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn next_unsigned<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
|
||||
where
|
||||
F: FnOnce(u128) -> Option<T>
|
||||
|
@ -204,6 +217,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn next_signed<T: FromPrimitive, F>(&mut self, f: F) -> ReaderResult<T>
|
||||
where
|
||||
F: FnOnce(i128) -> Option<T>
|
||||
|
@ -353,6 +367,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn open_record(&mut self, arity: Option<usize>) -> ReaderResult<B::Type> {
|
||||
self.next_compound(Tag::Record, ExpectedKind::Record(arity))?;
|
||||
let mut b = B::Type::default();
|
||||
|
@ -360,6 +375,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
Ok(b)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn open_sequence_or_set(&mut self) -> ReaderResult<B::Item> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
Tag::Sequence => {
|
||||
|
@ -375,41 +391,49 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn open_sequence(&mut self) -> ReaderResult<()> {
|
||||
self.next_compound(Tag::Sequence, ExpectedKind::Sequence)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn open_set(&mut self) -> ReaderResult<()> {
|
||||
self.next_compound(Tag::Set, ExpectedKind::Set)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn open_dictionary(&mut self) -> ReaderResult<()> {
|
||||
self.next_compound(Tag::Dictionary, ExpectedKind::Dictionary)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn boundary(&mut self, _b: &B::Type) -> ReaderResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn close_compound(&mut self, _b: &mut B::Type, _i: &B::Item) -> ReaderResult<bool> {
|
||||
Ok(self.peekend()?)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn open_embedded(&mut self) -> ReaderResult<()> {
|
||||
self.next_compound(Tag::Embedded, ExpectedKind::Embedded)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn close_embedded(&mut self) -> ReaderResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
type Mark = S::Mark;
|
||||
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
self.source.mark()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
self.source.restore(mark)
|
||||
}
|
||||
|
@ -462,6 +486,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn next_boolean(&mut self) -> ReaderResult<bool> {
|
||||
match self.peek_next_nonannotation_tag()? {
|
||||
Tag::False => { self.skip()?; Ok(false) }
|
||||
|
@ -551,6 +576,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode<N::Embedded>, S: BinarySource<
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn decodestr(cow: Cow<'_, [u8]>) -> io::Result<Cow<'_, str>> {
|
||||
match cow {
|
||||
Cow::Borrowed(bs) =>
|
||||
|
|
|
@ -16,6 +16,7 @@ use super::super::writer::{Writer, CompoundWriter, varint};
|
|||
pub struct PackedWriter<W: io::Write>(Suspendable<W>);
|
||||
|
||||
impl PackedWriter<&mut Vec<u8>> {
|
||||
#[inline(always)]
|
||||
pub fn encode<N: NestedValue, Enc: DomainEncode<N::Embedded>>(
|
||||
enc: &mut Enc,
|
||||
v: &N,
|
||||
|
@ -25,24 +26,29 @@ impl PackedWriter<&mut Vec<u8>> {
|
|||
Ok(buf)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn encode_iovalue(v: &IOValue) -> io::Result<Vec<u8>> {
|
||||
Self::encode(&mut IOValueDomainCodec, v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: io::Write> PackedWriter<W> {
|
||||
#[inline(always)]
|
||||
pub fn new(write: W) -> Self {
|
||||
PackedWriter(Suspendable::new(write))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn w(&mut self) -> &mut W {
|
||||
self.0.deref_mut()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_byte(&mut self, b: u8) -> io::Result<()> {
|
||||
self.w().write_all(&[b])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_medium_integer(&mut self, bs: &[u8]) -> io::Result<()> {
|
||||
let count: u8 = bs.len().try_into().unwrap();
|
||||
if !(1..=16).contains(&count) { panic!("Invalid medium_integer count: {}", count) }
|
||||
|
@ -50,16 +56,19 @@ impl<W: io::Write> PackedWriter<W> {
|
|||
self.w().write_all(bs)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_atom(&mut self, tag: Tag, bs: &[u8]) -> io::Result<()> {
|
||||
self.write_byte(tag.into())?;
|
||||
varint(&mut self.w(), bs.len().try_into().unwrap())?;
|
||||
self.w().write_all(bs)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn suspend(&mut self) -> Self {
|
||||
PackedWriter(self.0.suspend())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn resume(&mut self, other: Self) {
|
||||
self.0.resume(other.0)
|
||||
}
|
||||
|
@ -68,30 +77,37 @@ impl<W: io::Write> PackedWriter<W> {
|
|||
pub struct BinaryOrderWriter(Vec<Vec<u8>>);
|
||||
|
||||
impl BinaryOrderWriter {
|
||||
#[inline(always)]
|
||||
fn new() -> Self {
|
||||
BinaryOrderWriter(vec![vec![]])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pop(&mut self) -> PackedWriter<Vec<u8>> {
|
||||
PackedWriter::new(self.0.pop().unwrap())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn push(&mut self, w: PackedWriter<Vec<u8>>) {
|
||||
self.0.push(w.0.take())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn items(&self) -> &Vec<Vec<u8>> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn items_mut(&mut self) -> &mut Vec<Vec<u8>> {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn buffer(&mut self) -> &mut Vec<u8> {
|
||||
self.0.last_mut().unwrap()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn finish<W: WriteWriter>(mut self, w: &mut W) -> io::Result<()> {
|
||||
if !self.buffer().is_empty() { panic!("Missing final boundary()"); }
|
||||
self.items_mut().pop();
|
||||
|
@ -106,18 +122,22 @@ impl BinaryOrderWriter {
|
|||
|
||||
pub trait WriteWriter: Writer {
|
||||
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()>;
|
||||
|
||||
#[inline(always)]
|
||||
fn write_tag(&mut self, tag: Tag) -> io::Result<()> {
|
||||
self.write_raw_bytes(&[tag.into()])
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: io::Write> WriteWriter for PackedWriter<W> {
|
||||
#[inline(always)]
|
||||
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
|
||||
self.w().write_all(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl WriteWriter for BinaryOrderWriter {
|
||||
#[inline(always)]
|
||||
fn write_raw_bytes(&mut self, v: &[u8]) -> io::Result<()> {
|
||||
use io::Write;
|
||||
self.buffer().write_all(v)
|
||||
|
@ -125,7 +145,7 @@ impl WriteWriter for BinaryOrderWriter {
|
|||
}
|
||||
|
||||
impl<W: io::Write> CompoundWriter for PackedWriter<W> {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
|
||||
if let Some(B::Item::Annotation) = b.opening {
|
||||
self.write_tag(Tag::Annotation)?;
|
||||
|
@ -135,7 +155,7 @@ impl<W: io::Write> CompoundWriter for PackedWriter<W> {
|
|||
}
|
||||
|
||||
impl CompoundWriter for BinaryOrderWriter {
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
fn boundary(&mut self, b: &B::Type) -> io::Result<()> {
|
||||
match b.closing {
|
||||
Some(B::Item::DictionaryValue) |
|
||||
|
@ -152,7 +172,7 @@ impl CompoundWriter for BinaryOrderWriter {
|
|||
|
||||
macro_rules! binary_order_writer_method {
|
||||
(mut $n:ident ($($argname:ident : $argty:ty),*) -> $retty:ty) =>
|
||||
(fn $n (&mut self, $($argname : $argty),*) -> $retty {
|
||||
(#[inline(always)] fn $n (&mut self, $($argname : $argty),*) -> $retty {
|
||||
(&mut PackedWriter::new(self.buffer())).$n($($argname),*)
|
||||
});
|
||||
}
|
||||
|
@ -165,9 +185,11 @@ impl Writer for BinaryOrderWriter {
|
|||
type DictWriter = BinaryOrderWriter;
|
||||
type EmbeddedWriter = PackedWriter<Vec<u8>>;
|
||||
|
||||
#[inline(always)]
|
||||
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
|
||||
Ok(self.pop())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
|
||||
self.push(ann);
|
||||
Ok(())
|
||||
|
@ -194,44 +216,54 @@ impl Writer for BinaryOrderWriter {
|
|||
binary_order_writer_method!(mut write_bytes(v: &[u8]) -> io::Result<()>);
|
||||
binary_order_writer_method!(mut write_symbol(v: &str) -> io::Result<()>);
|
||||
|
||||
#[inline(always)]
|
||||
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
|
||||
self.write_tag(Tag::Record)?;
|
||||
Ok(self.pop())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
|
||||
self.push(rec);
|
||||
self.write_tag(Tag::End)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
|
||||
self.write_tag(Tag::Sequence)?;
|
||||
Ok(self.pop())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
|
||||
self.push(seq);
|
||||
self.write_tag(Tag::End)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
|
||||
self.write_tag(Tag::Set)?;
|
||||
Ok(BinaryOrderWriter::new())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
|
||||
set.finish(self)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
|
||||
self.write_tag(Tag::Dictionary)?;
|
||||
Ok(BinaryOrderWriter::new())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
|
||||
dict.finish(self)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
|
||||
self.write_tag(Tag::Embedded)?;
|
||||
Ok(self.pop())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> io::Result<()> {
|
||||
self.push(ptr);
|
||||
Ok(())
|
||||
|
@ -254,49 +286,59 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
type DictWriter = BinaryOrderWriter;
|
||||
type EmbeddedWriter = Self;
|
||||
|
||||
#[inline(always)]
|
||||
fn start_annotations(&mut self) -> io::Result<Self::AnnWriter> {
|
||||
Ok(self.suspend())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_annotations(&mut self, ann: Self::AnnWriter) -> io::Result<()> {
|
||||
self.resume(ann);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_bool(&mut self, v: bool) -> io::Result<()> {
|
||||
self.write_tag(if v { Tag::True } else { Tag::False })
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_f32(&mut self, v: f32) -> io::Result<()> {
|
||||
self.write_tag(Tag::Float)?;
|
||||
self.write_raw_bytes(&u32::to_be_bytes(f32::to_bits(v)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_f64(&mut self, v: f64) -> io::Result<()> {
|
||||
self.write_tag(Tag::Double)?;
|
||||
self.write_raw_bytes(&u64::to_be_bytes(f64::to_bits(v)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i8(&mut self, v: i8) -> io::Result<()> {
|
||||
if v >= -3 && v <= 12 { return self.write_tag(Tag::SmallInteger(v)) }
|
||||
self.write_medium_integer(&[v as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u8(&mut self, v: u8) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i8(w) }
|
||||
self.write_medium_integer(&[0, v])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i16(&mut self, v: i16) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i8(w) }
|
||||
self.write_medium_integer(&[(v >> 8) as u8, (v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u16(&mut self, v: u16) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
||||
self.write_medium_integer(&[0, (v >> 8) as u8, (v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i32(&mut self, v: i32) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i16(w) }
|
||||
if fits_in_bytes!(v, 3) {
|
||||
|
@ -310,6 +352,7 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u32(&mut self, v: u32) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
||||
self.write_medium_integer(&[0,
|
||||
|
@ -319,6 +362,7 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i64(&mut self, v: i64) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i32(w) }
|
||||
if fits_in_bytes!(v, 5) {
|
||||
|
@ -355,6 +399,7 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u64(&mut self, v: u64) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
||||
self.write_medium_integer(&[0,
|
||||
|
@ -368,6 +413,7 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
(v & 255) as u8])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_i128(&mut self, v: i128) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i64(w) }
|
||||
let bs: [u8; 16] = v.to_be_bytes();
|
||||
|
@ -381,6 +427,7 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
self.write_medium_integer(&bs)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_u128(&mut self, v: u128) -> io::Result<()> {
|
||||
if let Ok(w) = v.try_into() { return self.write_i128(w) }
|
||||
let bs: [u8; 16] = v.to_be_bytes();
|
||||
|
@ -390,6 +437,7 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
self.write_raw_bytes(&bs)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_int(&mut self, v: &BigInt) -> io::Result<()> {
|
||||
match v.to_i8() {
|
||||
Some(n) => self.write_i8(n),
|
||||
|
@ -402,61 +450,74 @@ impl<W: io::Write> Writer for PackedWriter<W>
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_string(&mut self, v: &str) -> io::Result<()> {
|
||||
self.write_atom(Tag::String, v.as_bytes())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_bytes(&mut self, v: &[u8]) -> io::Result<()> {
|
||||
self.write_atom(Tag::ByteString, v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn write_symbol(&mut self, v: &str) -> io::Result<()> {
|
||||
self.write_atom(Tag::Symbol, v.as_bytes())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_record(&mut self, _field_count: Option<usize>) -> io::Result<Self::RecWriter> {
|
||||
self.write_tag(Tag::Record)?;
|
||||
Ok(self.suspend())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_record(&mut self, rec: Self::RecWriter) -> io::Result<()> {
|
||||
self.resume(rec);
|
||||
self.write_tag(Tag::End)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_sequence(&mut self, _item_count: Option<usize>) -> io::Result<Self::SeqWriter> {
|
||||
self.write_tag(Tag::Sequence)?;
|
||||
Ok(self.suspend())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_sequence(&mut self, seq: Self::SeqWriter) -> io::Result<()> {
|
||||
self.resume(seq);
|
||||
self.write_tag(Tag::End)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_set(&mut self, _item_count: Option<usize>) -> io::Result<Self::SetWriter> {
|
||||
self.write_tag(Tag::Set)?;
|
||||
Ok(BinaryOrderWriter::new())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_set(&mut self, set: Self::SetWriter) -> io::Result<()> {
|
||||
set.finish(self)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_dictionary(&mut self, _entry_count: Option<usize>) -> io::Result<Self::DictWriter> {
|
||||
self.write_tag(Tag::Dictionary)?;
|
||||
Ok(BinaryOrderWriter::new())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_dictionary(&mut self, dict: Self::DictWriter) -> io::Result<()> {
|
||||
dict.finish(self)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn start_embedded(&mut self) -> io::Result<Self::EmbeddedWriter> {
|
||||
self.write_tag(Tag::Embedded)?;
|
||||
Ok(self.suspend())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> io::Result<()> {
|
||||
self.resume(ann);
|
||||
Ok(())
|
||||
|
|
|
@ -262,6 +262,7 @@ pub struct IOBinarySource<R: io::Read + io::Seek> {
|
|||
}
|
||||
|
||||
impl<R: io::Read + io::Seek> IOBinarySource<R> {
|
||||
#[inline(always)]
|
||||
pub fn new(read: R) -> Self {
|
||||
IOBinarySource { read, buf: None }
|
||||
}
|
||||
|
@ -270,22 +271,26 @@ impl<R: io::Read + io::Seek> IOBinarySource<R> {
|
|||
impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
|
||||
type Mark = u64;
|
||||
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
Ok(self.read.stream_position()? - (if self.buf.is_some() { 1 } else { 0 }))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
self.read.seek(io::SeekFrom::Start(*mark))?;
|
||||
self.buf = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn skip(&mut self) -> io::Result<()> {
|
||||
if self.buf.is_none() { unreachable!(); }
|
||||
self.buf = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn peek(&mut self) -> io::Result<u8> {
|
||||
match self.buf {
|
||||
Some(b) => Ok(b),
|
||||
|
@ -303,6 +308,7 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
|
||||
if self.buf.is_some() { unreachable!(); }
|
||||
let mut bs = vec![0; count];
|
||||
|
@ -310,6 +316,7 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource<R> {
|
|||
Ok(Cow::Owned(bs))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
|
||||
if self.buf.is_some() { unreachable!(); }
|
||||
self.read.read_exact(bs)
|
||||
|
@ -322,6 +329,7 @@ pub struct BytesBinarySource<'de> {
|
|||
}
|
||||
|
||||
impl<'de> BytesBinarySource<'de> {
|
||||
#[inline(always)]
|
||||
pub fn new(bytes: &'de [u8]) -> Self {
|
||||
BytesBinarySource { bytes, index: 0 }
|
||||
}
|
||||
|
@ -330,21 +338,25 @@ impl<'de> BytesBinarySource<'de> {
|
|||
impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
|
||||
type Mark = usize;
|
||||
|
||||
#[inline(always)]
|
||||
fn mark(&mut self) -> io::Result<Self::Mark> {
|
||||
Ok(self.index)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn restore(&mut self, mark: &Self::Mark) -> io::Result<()> {
|
||||
self.index = *mark;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn skip(&mut self) -> io::Result<()> {
|
||||
if self.index >= self.bytes.len() { unreachable!(); }
|
||||
self.index += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn peek(&mut self) -> io::Result<u8> {
|
||||
if self.index >= self.bytes.len() {
|
||||
Err(io_eof())
|
||||
|
@ -353,6 +365,7 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn readbytes(&mut self, count: usize) -> io::Result<Cow<'de, [u8]>> {
|
||||
if self.index + count > self.bytes.len() {
|
||||
Err(io_eof())
|
||||
|
@ -363,6 +376,7 @@ impl<'de> BinarySource<'de> for BytesBinarySource<'de> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn readbytes_into(&mut self, bs: &mut [u8]) -> io::Result<()> {
|
||||
let count = bs.len();
|
||||
if self.index + count > self.bytes.len() {
|
||||
|
|
|
@ -28,18 +28,22 @@ impl<D: Domain> Domain for Arc<D> {}
|
|||
pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
|
||||
type Embedded: Embeddable;
|
||||
|
||||
#[inline(always)]
|
||||
fn new<V>(v: V) -> Self where Value<Self>: From<V> {
|
||||
Value::from(v).wrap()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn domain<E>(e: E) -> Self where Self::Embedded: From<E> {
|
||||
Value::Embedded(e.into()).wrap()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn symbol(n: &str) -> Self {
|
||||
Value::symbol(n).wrap()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn bytestring<'a, V: Into<Cow<'a, [u8]>>>(v: V) -> Self {
|
||||
Value::bytestring(v).wrap()
|
||||
}
|
||||
|
@ -51,6 +55,7 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord {
|
|||
fn pieces(self) -> (Annotations<Self>, Value<Self>);
|
||||
fn value_owned(self) -> Value<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn value_class(&self) -> ValueClass {
|
||||
self.value().value_class()
|
||||
}
|
||||
|
@ -144,34 +149,42 @@ pub struct Double(pub f64);
|
|||
pub struct Record<N>(pub Vec<N>);
|
||||
|
||||
impl<N> Record<N> {
|
||||
#[inline(always)]
|
||||
pub fn label(&self) -> &N {
|
||||
&self.0[0]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn label_mut(&mut self) -> &mut N {
|
||||
&mut self.0[0]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn arity(&self) -> usize {
|
||||
self.0.len() - 1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fields(&self) -> &[N] {
|
||||
&self.0[1..]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fields_mut(&mut self) -> &mut [N] {
|
||||
&mut self.0[1..]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fields_vec(&self) -> &Vec<N> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fields_vec_mut(&mut self) -> &mut Vec<N> {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn finish(self) -> Value<N> where N: NestedValue {
|
||||
Value::Record(self)
|
||||
}
|
||||
|
@ -388,10 +401,12 @@ impl<N: NestedValue> Value<N> {
|
|||
Error::Expected(k, Received::ReceivedOtherValue(format!("{:?}", self.clone().wrap())))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_boolean(&self) -> bool {
|
||||
self.as_boolean().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_boolean(&self) -> Option<bool> {
|
||||
if let Value::Boolean(b) = self {
|
||||
Some(*b)
|
||||
|
@ -400,6 +415,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_boolean_mut(&mut self) -> Option<&mut bool> {
|
||||
if let Value::Boolean(b) = self {
|
||||
Some(b)
|
||||
|
@ -408,14 +424,17 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_boolean(&self) -> Result<bool, Error> {
|
||||
self.as_boolean().ok_or_else(|| self.expected(ExpectedKind::Boolean))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_float(&self) -> bool {
|
||||
self.as_float().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_float(&self) -> Option<&Float> {
|
||||
if let Value::Float(f) = self {
|
||||
Some(f)
|
||||
|
@ -424,6 +443,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_float_mut(&mut self) -> Option<&mut Float> {
|
||||
if let Value::Float(f) = self {
|
||||
Some(f)
|
||||
|
@ -432,30 +452,37 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_float(&self) -> Result<&Float, Error> {
|
||||
self.as_float().ok_or_else(|| self.expected(ExpectedKind::Float))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_f32(&self) -> bool {
|
||||
self.is_float()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_f32(&self) -> Option<f32> {
|
||||
self.as_float().map(|f| f.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_f32_mut(&mut self) -> Option<&mut f32> {
|
||||
self.as_float_mut().map(|f| &mut f.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_f32(&self) -> Result<f32, Error> {
|
||||
self.to_float().map(|f| f.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_double(&self) -> bool {
|
||||
self.as_double().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_double(&self) -> Option<&Double> {
|
||||
if let Value::Double(f) = self {
|
||||
Some(f)
|
||||
|
@ -464,6 +491,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_double_mut(&mut self) -> Option<&mut Double> {
|
||||
if let Value::Double(f) = self {
|
||||
Some(f)
|
||||
|
@ -472,30 +500,37 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_double(&self) -> Result<&Double, Error> {
|
||||
self.as_double().ok_or_else(|| self.expected(ExpectedKind::Double))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_f64(&self) -> bool {
|
||||
self.is_double()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_f64(&self) -> Option<f64> {
|
||||
self.as_double().map(|f| f.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_f64_mut(&mut self) -> Option<&mut f64> {
|
||||
self.as_double_mut().map(|f| &mut f.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_f64(&self) -> Result<f64, Error> {
|
||||
self.to_double().map(|f| f.0)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_signedinteger(&self) -> bool {
|
||||
self.as_signedinteger().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_signedinteger(&self) -> Option<&SignedInteger> {
|
||||
if let Value::SignedInteger(n) = self {
|
||||
Some(n)
|
||||
|
@ -504,6 +539,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_signedinteger_mut(&mut self) -> Option<&mut SignedInteger> {
|
||||
if let Value::SignedInteger(n) = self {
|
||||
Some(n)
|
||||
|
@ -512,47 +548,67 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_signedinteger(&self) -> Result<&SignedInteger, Error> {
|
||||
self.as_signedinteger().ok_or_else(|| self.expected(ExpectedKind::SignedInteger))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_i(&self) -> bool {
|
||||
self.as_i().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_i(&self) -> Option<i128> {
|
||||
self.as_signedinteger().and_then(|n| n.try_into().ok())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_i(&self) -> Result<i128, Error> {
|
||||
self.as_i().ok_or_else(|| self.expected(ExpectedKind::SignedIntegerI128))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_u(&self) -> bool {
|
||||
self.as_u().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_u(&self) -> Option<u128> {
|
||||
self.as_signedinteger().and_then(|n| n.try_into().ok())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_u(&self) -> Result<u128, Error> {
|
||||
self.as_u().ok_or_else(|| self.expected(ExpectedKind::SignedIntegerU128))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_u8(&self) -> Option<u8> { self.as_u().and_then(|i| i.to_u8()) }
|
||||
#[inline(always)]
|
||||
pub fn as_i8(&self) -> Option<i8> { self.as_i().and_then(|i| i.to_i8()) }
|
||||
#[inline(always)]
|
||||
pub fn as_u16(&self) -> Option<u16> { self.as_u().and_then(|i| i.to_u16()) }
|
||||
#[inline(always)]
|
||||
pub fn as_i16(&self) -> Option<i16> { self.as_i().and_then(|i| i.to_i16()) }
|
||||
#[inline(always)]
|
||||
pub fn as_u32(&self) -> Option<u32> { self.as_u().and_then(|i| i.to_u32()) }
|
||||
#[inline(always)]
|
||||
pub fn as_i32(&self) -> Option<i32> { self.as_i().and_then(|i| i.to_i32()) }
|
||||
#[inline(always)]
|
||||
pub fn as_u64(&self) -> Option<u64> { self.as_u().and_then(|i| i.to_u64()) }
|
||||
#[inline(always)]
|
||||
pub fn as_i64(&self) -> Option<i64> { self.as_i().and_then(|i| i.to_i64()) }
|
||||
#[inline(always)]
|
||||
pub fn as_u128(&self) -> Option<u128> { self.as_u().and_then(|i| i.to_u128()) }
|
||||
#[inline(always)]
|
||||
pub fn as_i128(&self) -> Option<i128> { self.as_i().and_then(|i| i.to_i128()) }
|
||||
#[inline(always)]
|
||||
pub fn as_usize(&self) -> Option<usize> { self.as_u().and_then(|i| i.to_usize()) }
|
||||
#[inline(always)]
|
||||
pub fn as_isize(&self) -> Option<isize> { self.as_i().and_then(|i| i.to_isize()) }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_i8(&self) -> Result<i8, Error> {
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
|
@ -560,6 +616,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_u8(&self) -> Result<u8, Error> {
|
||||
match self.as_u() {
|
||||
Some(i) => i.to_u8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
|
@ -567,6 +624,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_i16(&self) -> Result<i16, Error> {
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i16().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
|
@ -574,6 +632,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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))),
|
||||
|
@ -581,6 +640,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_i32(&self) -> Result<i32, Error> {
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i32().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
|
@ -588,6 +648,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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))),
|
||||
|
@ -595,6 +656,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_i64(&self) -> Result<i64, Error> {
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_i64().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
|
@ -602,6 +664,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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))),
|
||||
|
@ -609,6 +672,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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))),
|
||||
|
@ -616,6 +680,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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))),
|
||||
|
@ -623,6 +688,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_isize(&self) -> Result<isize, Error> {
|
||||
match self.as_i() {
|
||||
Some(i) => i.to_isize().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
|
@ -630,6 +696,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_usize(&self) -> Result<usize, Error> {
|
||||
match self.as_u() {
|
||||
Some(i) => i.to_usize().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))),
|
||||
|
@ -637,16 +704,19 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_char(&self) -> Result<char, Error> {
|
||||
let fs = self.to_simple_record("UnicodeScalar", Some(1))?;
|
||||
let c = fs[0].value().to_u32()?;
|
||||
char::try_from(c).map_err(|_| Error::InvalidUnicodeScalar(c))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_string(&self) -> bool {
|
||||
self.as_string().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_string(&self) -> Option<&String> {
|
||||
if let Value::String(s) = self {
|
||||
Some(s)
|
||||
|
@ -655,6 +725,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_string_mut(&mut self) -> Option<&mut String> {
|
||||
if let Value::String(s) = self {
|
||||
Some(s)
|
||||
|
@ -663,18 +734,22 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_string(&self) -> Result<&String, Error> {
|
||||
self.as_string().ok_or_else(|| self.expected(ExpectedKind::String))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn bytestring<'a, V: Into<Cow<'a, [u8]>>>(v: V) -> Self {
|
||||
Value::ByteString(v.into().into_owned())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_bytestring(&self) -> bool {
|
||||
self.as_bytestring().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_bytestring(&self) -> Option<&Vec<u8>> {
|
||||
if let Value::ByteString(s) = self {
|
||||
Some(s)
|
||||
|
@ -683,6 +758,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_bytestring_mut(&mut self) -> Option<&mut Vec<u8>> {
|
||||
if let Value::ByteString(s) = self {
|
||||
Some(s)
|
||||
|
@ -691,18 +767,22 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_bytestring(&self) -> Result<&Vec<u8>, Error> {
|
||||
self.as_bytestring().ok_or_else(|| self.expected(ExpectedKind::ByteString))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn symbol(s: &str) -> Value<N> {
|
||||
Value::Symbol(s.to_string())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_symbol(&self) -> bool {
|
||||
self.as_symbol().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_symbol(&self) -> Option<&String> {
|
||||
if let Value::Symbol(s) = self {
|
||||
Some(s)
|
||||
|
@ -711,6 +791,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_symbol_mut(&mut self) -> Option<&mut String> {
|
||||
if let Value::Symbol(s) = self {
|
||||
Some(s)
|
||||
|
@ -719,20 +800,24 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_symbol(&self) -> Result<&String, Error> {
|
||||
self.as_symbol().ok_or_else(|| self.expected(ExpectedKind::Symbol))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn record(label: N, expected_arity: usize) -> Record<N> {
|
||||
let mut v = Vec::with_capacity(expected_arity + 1);
|
||||
v.push(label);
|
||||
Record(v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_record(&self) -> bool {
|
||||
matches!(*self, Value::Record(_))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_record(&self, arity: Option<usize>) -> Option<&Record<N>> {
|
||||
if let Value::Record(r) = self {
|
||||
match arity {
|
||||
|
@ -745,6 +830,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_record(self) -> Option<Record<N>> {
|
||||
match self {
|
||||
Value::Record(r) => Some(r),
|
||||
|
@ -752,6 +838,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_record_mut(&mut self, arity: Option<usize>) -> Option<&mut Record<N>> {
|
||||
if let Value::Record(r) = self {
|
||||
match arity {
|
||||
|
@ -764,28 +851,34 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_record(&self, arity: Option<usize>) -> Result<&Record<N>, Error> {
|
||||
self.as_record(arity).ok_or_else(|| self.expected(ExpectedKind::Record(arity)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn simple_record(label: &str, expected_arity: usize) -> Record<N> {
|
||||
Self::record(N::symbol(label), expected_arity)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn simple_record0(label: &str) -> Value<N> {
|
||||
Self::simple_record(label, 0).finish()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn simple_record1(label: &str, field: N) -> Value<N> {
|
||||
let mut r = Self::simple_record(label, 1);
|
||||
r.fields_vec_mut().push(field);
|
||||
r.finish()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_simple_record(&self, label: &str, arity: Option<usize>) -> bool {
|
||||
self.as_simple_record(label, arity).is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_simple_record(&self, label: &str, arity: Option<usize>) -> Option<&[N]> {
|
||||
self.as_record(arity).and_then(|r| {
|
||||
match r.label().value() {
|
||||
|
@ -795,6 +888,7 @@ impl<N: NestedValue> Value<N> {
|
|||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_simple_record(&self, label: &str, arity: Option<usize>) ->
|
||||
Result<&[N], Error>
|
||||
{
|
||||
|
@ -802,6 +896,7 @@ impl<N: NestedValue> Value<N> {
|
|||
.ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_option(&self) -> Result<Option<&N>, Error> {
|
||||
match self.as_simple_record("None", Some(0)) {
|
||||
Some(_fs) => Ok(None),
|
||||
|
@ -812,10 +907,12 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_sequence(&self) -> bool {
|
||||
self.as_sequence().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_sequence(&self) -> Option<&Vec<N>> {
|
||||
if let Value::Sequence(s) = self {
|
||||
Some(s)
|
||||
|
@ -824,6 +921,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_sequence(self) -> Option<Vec<N>> {
|
||||
match self {
|
||||
Value::Sequence(s) => Some(s),
|
||||
|
@ -831,6 +929,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_sequence_mut(&mut self) -> Option<&mut Vec<N>> {
|
||||
if let Value::Sequence(s) = self {
|
||||
Some(s)
|
||||
|
@ -839,14 +938,17 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_sequence(&self) -> Result<&Vec<N>, Error> {
|
||||
self.as_sequence().ok_or_else(|| self.expected(ExpectedKind::Sequence))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_set(&self) -> bool {
|
||||
self.as_set().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_set(&self) -> Option<&Set<N>> {
|
||||
if let Value::Set(s) = self {
|
||||
Some(s)
|
||||
|
@ -855,6 +957,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_set(self) -> Option<Set<N>> {
|
||||
match self {
|
||||
Value::Set(s) => Some(s),
|
||||
|
@ -862,6 +965,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_set_mut(&mut self) -> Option<&mut Set<N>> {
|
||||
if let Value::Set(s) = self {
|
||||
Some(s)
|
||||
|
@ -870,14 +974,17 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_set(&self) -> Result<&Set<N>, Error> {
|
||||
self.as_set().ok_or_else(|| self.expected(ExpectedKind::Set))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_dictionary(&self) -> bool {
|
||||
self.as_dictionary().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_dictionary(&self) -> Option<&Map<N, N>> {
|
||||
if let Value::Dictionary(s) = self {
|
||||
Some(s)
|
||||
|
@ -886,6 +993,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn into_dictionary(self) -> Option<Map<N, N>> {
|
||||
match self {
|
||||
Value::Dictionary(s) => Some(s),
|
||||
|
@ -893,6 +1001,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_dictionary_mut(&mut self) -> Option<&mut Map<N, N>> {
|
||||
if let Value::Dictionary(s) = self {
|
||||
Some(s)
|
||||
|
@ -901,14 +1010,17 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_dictionary(&self) -> Result<&Map<N, N>, Error> {
|
||||
self.as_dictionary().ok_or_else(|| self.expected(ExpectedKind::Dictionary))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_embedded(&self) -> bool {
|
||||
self.as_embedded().is_some()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_embedded(&self) -> Option<&N::Embedded> {
|
||||
if let Value::Embedded(d) = self {
|
||||
Some(d)
|
||||
|
@ -917,6 +1029,7 @@ impl<N: NestedValue> Value<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_embedded(&self) -> Result<&N::Embedded, Error> {
|
||||
self.as_embedded().ok_or_else(|| self.expected(ExpectedKind::Embedded))
|
||||
}
|
||||
|
@ -995,12 +1108,14 @@ impl<N: NestedValue> Value<N> {
|
|||
impl<N: NestedValue> Index<usize> for Value<N> {
|
||||
type Output = N;
|
||||
|
||||
#[inline(always)]
|
||||
fn index(&self, i: usize) -> &Self::Output {
|
||||
&self.as_sequence().unwrap()[i]
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NestedValue> IndexMut<usize> for Value<N> {
|
||||
#[inline(always)]
|
||||
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
|
||||
&mut self.as_sequence_mut().unwrap()[i]
|
||||
}
|
||||
|
@ -1009,6 +1124,7 @@ impl<N: NestedValue> IndexMut<usize> for Value<N> {
|
|||
impl<N: NestedValue> Index<&N> for Value<N> {
|
||||
type Output = N;
|
||||
|
||||
#[inline(always)]
|
||||
fn index(&self, i: &N) -> &Self::Output {
|
||||
&(*self.as_dictionary().unwrap())[i]
|
||||
}
|
||||
|
@ -1035,14 +1151,17 @@ impl<'de> serde::Deserialize<'de> for UnwrappedIOValue {
|
|||
pub struct Annotations<N: NestedValue>(Option<Box<Vec<N>>>);
|
||||
|
||||
impl<N: NestedValue> Annotations<N> {
|
||||
#[inline(always)]
|
||||
pub fn empty() -> Self {
|
||||
Annotations(None)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn new(anns: Option<Vec<N>>) -> Self {
|
||||
Annotations(anns.map(Box::new))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn maybe_slice(&self) -> Option<&[N]> {
|
||||
match &self.0 {
|
||||
None => None,
|
||||
|
@ -1050,10 +1169,12 @@ impl<N: NestedValue> Annotations<N> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn slice(&self) -> &[N] {
|
||||
self.maybe_slice().unwrap_or(&[])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn to_vec(self) -> Vec<N> {
|
||||
use std::ops::DerefMut;
|
||||
self.0.map(|mut b| std::mem::take(b.deref_mut())).unwrap_or_default()
|
||||
|
@ -1101,12 +1222,14 @@ impl<N: NestedValue> Annotations<N> {
|
|||
pub struct AnnotatedValue<N: NestedValue>(pub Annotations<N>, pub Value<N>);
|
||||
|
||||
impl<N: NestedValue> AnnotatedValue<N> {
|
||||
#[inline(always)]
|
||||
fn new(anns: Annotations<N>, value: Value<N>) -> Self {
|
||||
AnnotatedValue(anns, value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NestedValue> PartialEq for AnnotatedValue<N> {
|
||||
#[inline(always)]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.1.eq(&other.1)
|
||||
}
|
||||
|
@ -1115,18 +1238,21 @@ impl<N: NestedValue> PartialEq for AnnotatedValue<N> {
|
|||
impl<N: NestedValue> Eq for AnnotatedValue<N> {}
|
||||
|
||||
impl<N: NestedValue> Hash for AnnotatedValue<N> {
|
||||
#[inline(always)]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.1.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NestedValue> PartialOrd for AnnotatedValue<N> {
|
||||
#[inline(always)]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: NestedValue> Ord for AnnotatedValue<N> {
|
||||
#[inline(always)]
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.1.cmp(&other.1)
|
||||
}
|
||||
|
@ -1138,10 +1264,12 @@ impl<N: NestedValue> Ord for AnnotatedValue<N> {
|
|||
pub struct PlainValue<D: Embeddable>(AnnotatedValue<PlainValue<D>>);
|
||||
|
||||
impl<D: Embeddable> PlainValue<D> {
|
||||
#[inline(always)]
|
||||
pub fn annotations_mut(&mut self) -> &mut Annotations<Self> {
|
||||
&mut (self.0).0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn value_mut(&mut self) -> &mut Value<Self> {
|
||||
&mut (self.0).1
|
||||
}
|
||||
|
@ -1150,23 +1278,28 @@ impl<D: Embeddable> PlainValue<D> {
|
|||
impl<D: Embeddable> NestedValue for PlainValue<D> {
|
||||
type Embedded = D;
|
||||
|
||||
#[inline(always)]
|
||||
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
|
||||
PlainValue(AnnotatedValue::new(anns, v))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn annotations(&self) -> &Annotations<Self> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value(&self) -> &Value<Self> {
|
||||
&(self.0).1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
|
||||
let AnnotatedValue(anns, v) = self.0;
|
||||
(anns, v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value_owned(self) -> Value<Self> {
|
||||
(self.0).1
|
||||
}
|
||||
|
@ -1188,18 +1321,22 @@ pub struct RcValue<D: Embeddable>(Rc<AnnotatedValue<RcValue<D>>>);
|
|||
impl<D: Embeddable> NestedValue for RcValue<D> {
|
||||
type Embedded = D;
|
||||
|
||||
#[inline(always)]
|
||||
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
|
||||
RcValue(Rc::new(AnnotatedValue::new(anns, v)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn annotations(&self) -> &Annotations<Self> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value(&self) -> &Value<Self> {
|
||||
&(self.0).1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
|
||||
match Rc::try_unwrap(self.0) {
|
||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||
|
@ -1207,6 +1344,7 @@ impl<D: Embeddable> NestedValue for RcValue<D> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value_owned(self) -> Value<Self> {
|
||||
Rc::try_unwrap(self.0).unwrap_or_else(|_| panic!("value_owned on RcValue with refcount greater than one")).1
|
||||
}
|
||||
|
@ -1226,18 +1364,22 @@ pub struct ArcValue<D: Embeddable>(Arc<AnnotatedValue<ArcValue<D>>>);
|
|||
impl<D: Embeddable> NestedValue for ArcValue<D> {
|
||||
type Embedded = D;
|
||||
|
||||
#[inline(always)]
|
||||
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
|
||||
ArcValue(Arc::new(AnnotatedValue::new(anns, v)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn annotations(&self) -> &Annotations<Self> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value(&self) -> &Value<Self> {
|
||||
&(self.0).1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
|
||||
match Arc::try_unwrap(self.0) {
|
||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||
|
@ -1245,6 +1387,7 @@ impl<D: Embeddable> NestedValue for ArcValue<D> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value_owned(self) -> Value<Self> {
|
||||
Arc::try_unwrap(self.0).unwrap_or_else(|_| panic!("value_owned on ArcValue with refcount greater than one")).1
|
||||
}
|
||||
|
@ -1267,18 +1410,22 @@ impl Domain for IOValue {}
|
|||
impl NestedValue for IOValue {
|
||||
type Embedded = Self;
|
||||
|
||||
#[inline(always)]
|
||||
fn wrap(anns: Annotations<Self>, v: Value<Self>) -> Self {
|
||||
IOValue(Arc::new(AnnotatedValue::new(anns, v)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn annotations(&self) -> &Annotations<Self> {
|
||||
&(self.0).0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value(&self) -> &Value<Self> {
|
||||
&(self.0).1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
|
||||
match Arc::try_unwrap(self.0) {
|
||||
Ok(AnnotatedValue(anns, v)) => (anns, v),
|
||||
|
@ -1286,6 +1433,7 @@ impl NestedValue for IOValue {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value_owned(self) -> Value<Self> {
|
||||
match Arc::try_unwrap(self.0) {
|
||||
Ok(AnnotatedValue(_anns, v)) => v,
|
||||
|
@ -1324,6 +1472,7 @@ impl<D: Embeddable> Debug for DummyValue<D> {
|
|||
}
|
||||
|
||||
impl<D: Embeddable> DummyValue<D> {
|
||||
#[inline(always)]
|
||||
pub fn new() -> Self {
|
||||
DummyValue(AnnotatedValue::new(Annotations::empty(), Value::Boolean(false)))
|
||||
}
|
||||
|
@ -1332,22 +1481,27 @@ impl<D: Embeddable> DummyValue<D> {
|
|||
impl<D: Embeddable> NestedValue for DummyValue<D> {
|
||||
type Embedded = D;
|
||||
|
||||
#[inline(always)]
|
||||
fn wrap(_anns: Annotations<Self>, _v: Value<Self>) -> Self {
|
||||
DummyValue::new()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn annotations(&self) -> &Annotations<Self> {
|
||||
&self.0.0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value(&self) -> &Value<Self> {
|
||||
&self.0.1
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn pieces(self) -> (Annotations<Self>, Value<Self>) {
|
||||
(self.0.0, self.0.1)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn value_owned(self) -> Value<Self> {
|
||||
self.0.1
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ impl<T> Suspendable<T> {
|
|||
Suspendable::Active(t)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn suspend(&mut self) -> Self {
|
||||
match self {
|
||||
Suspendable::Active(_) => std::mem::replace(self, Suspendable::Suspended),
|
||||
|
@ -18,6 +19,7 @@ impl<T> Suspendable<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn resume(&mut self, other: Self) {
|
||||
match self {
|
||||
Suspendable::Suspended =>
|
||||
|
@ -31,6 +33,7 @@ impl<T> Suspendable<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn take(self) -> T {
|
||||
match self {
|
||||
Suspendable::Active(t) => t,
|
||||
|
@ -42,6 +45,7 @@ impl<T> Suspendable<T> {
|
|||
|
||||
impl<T> Deref for Suspendable<T> {
|
||||
type Target = T;
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
Suspendable::Suspended => panic!("Suspended Suspendable at deref"),
|
||||
|
@ -51,6 +55,7 @@ impl<T> Deref for Suspendable<T> {
|
|||
}
|
||||
|
||||
impl<T> DerefMut for Suspendable<T> {
|
||||
#[inline(always)]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
match self {
|
||||
Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"),
|
||||
|
|
Loading…
Reference in New Issue