Inline the heck out of the binary codec for a ~5% speedup

This commit is contained in:
Tony Garnock-Jones 2021-09-30 13:07:01 +02:00
parent e31cf739df
commit e2a4e3d6cb
6 changed files with 266 additions and 6 deletions

View File

@ -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)

View File

@ -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) =>

View File

@ -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(())

View File

@ -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() {

View File

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

View File

@ -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"),