diff --git a/implementations/rust/preserves/src/value/magic.rs b/implementations/rust/preserves/src/value/magic.rs index d5b04b4..9fdde61 100644 --- a/implementations/rust/preserves/src/value/magic.rs +++ b/implementations/rust/preserves/src/value/magic.rs @@ -14,14 +14,14 @@ impl<'de> serde::de::Visitor<'de> for IOValueVisitor { } } -#[inline] +#[inline(always)] pub fn output_value(serializer: S, v: IOValue) -> Result { 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 { deserializer.deserialize_newtype_struct(MAGIC, IOValueVisitor) diff --git a/implementations/rust/preserves/src/value/packed/reader.rs b/implementations/rust/preserves/src/value/packed/reader.rs index 388fef0..5ed443f 100644 --- a/implementations/rust/preserves/src/value/packed/reader.rs +++ b/implementations/rust/preserves/src/value/packed/reader.rs @@ -41,21 +41,27 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< for PackedReader<'de, 'src, N, Dec, S> { type Mark = S::Mark; + #[inline(always)] fn mark(&mut self) -> io::Result { 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 { self.source.peek() } + #[inline(always)] fn readbytes(&mut self, count: usize) -> io::Result> { 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: I) -> error::Error { } impl<'de, 'src, N: NestedValue, Dec: DomainDecode, 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 { let v = self.peek()?; self.skip()?; @@ -83,6 +91,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< } } + #[inline(always)] fn varint(&mut self) -> io::Result { let mut shift = 0; let mut acc: usize = 0; @@ -94,6 +103,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< } } + #[inline(always)] fn peekend(&mut self) -> io::Result { if self.peek()? == Tag::End.into() { self.skip()?; @@ -103,6 +113,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< } } + #[inline(always)] fn peek_next_nonannotation_tag(&mut self) -> ReaderResult { loop { match Tag::try_from(self.peek()?)? { @@ -137,6 +148,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< } } + #[inline(always)] fn read_signed_integer(&mut self, count: usize) -> io::Result { if count == 0 { return Ok(SignedInteger::from(0_i128)); @@ -173,6 +185,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< } } + #[inline(always)] fn next_unsigned(&mut self, f: F) -> ReaderResult where F: FnOnce(u128) -> Option @@ -204,6 +217,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< } } + #[inline(always)] fn next_signed(&mut self, f: F) -> ReaderResult where F: FnOnce(i128) -> Option @@ -353,6 +367,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< })) } + #[inline(always)] fn open_record(&mut self, arity: Option) -> ReaderResult { 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, S: BinarySource< Ok(b) } + #[inline(always)] fn open_sequence_or_set(&mut self) -> ReaderResult { match self.peek_next_nonannotation_tag()? { Tag::Sequence => { @@ -375,41 +391,49 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, 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 { 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.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, S: BinarySource< } } + #[inline(always)] fn next_boolean(&mut self) -> ReaderResult { match self.peek_next_nonannotation_tag()? { Tag::False => { self.skip()?; Ok(false) } @@ -551,6 +576,7 @@ impl<'de, 'src, N: NestedValue, Dec: DomainDecode, S: BinarySource< } } +#[inline(always)] fn decodestr(cow: Cow<'_, [u8]>) -> io::Result> { match cow { Cow::Borrowed(bs) => diff --git a/implementations/rust/preserves/src/value/packed/writer.rs b/implementations/rust/preserves/src/value/packed/writer.rs index 6a0953f..4dfecbb 100644 --- a/implementations/rust/preserves/src/value/packed/writer.rs +++ b/implementations/rust/preserves/src/value/packed/writer.rs @@ -16,6 +16,7 @@ use super::super::writer::{Writer, CompoundWriter, varint}; pub struct PackedWriter(Suspendable); impl PackedWriter<&mut Vec> { + #[inline(always)] pub fn encode>( enc: &mut Enc, v: &N, @@ -25,24 +26,29 @@ impl PackedWriter<&mut Vec> { Ok(buf) } + #[inline(always)] pub fn encode_iovalue(v: &IOValue) -> io::Result> { Self::encode(&mut IOValueDomainCodec, v) } } impl PackedWriter { + #[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 PackedWriter { 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 PackedWriter { pub struct BinaryOrderWriter(Vec>); impl BinaryOrderWriter { + #[inline(always)] fn new() -> Self { BinaryOrderWriter(vec![vec![]]) } + #[inline(always)] fn pop(&mut self) -> PackedWriter> { PackedWriter::new(self.0.pop().unwrap()) } + #[inline(always)] fn push(&mut self, w: PackedWriter>) { self.0.push(w.0.take()) } + #[inline(always)] fn items(&self) -> &Vec> { &self.0 } + #[inline(always)] fn items_mut(&mut self) -> &mut Vec> { &mut self.0 } + #[inline(always)] fn buffer(&mut self) -> &mut Vec { self.0.last_mut().unwrap() } + #[inline(always)] fn finish(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 WriteWriter for PackedWriter { + #[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 CompoundWriter for PackedWriter { - #[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 CompoundWriter for PackedWriter { } 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>; + #[inline(always)] fn start_annotations(&mut self) -> io::Result { 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) -> io::Result { 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) -> io::Result { 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) -> io::Result { 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) -> io::Result { 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.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 Writer for PackedWriter type DictWriter = BinaryOrderWriter; type EmbeddedWriter = Self; + #[inline(always)] fn start_annotations(&mut self) -> io::Result { 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 Writer for PackedWriter (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 Writer for PackedWriter (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 Writer for PackedWriter (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 Writer for PackedWriter (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 Writer for PackedWriter 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 Writer for PackedWriter 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 Writer for PackedWriter } } + #[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) -> io::Result { 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) -> io::Result { 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) -> io::Result { 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) -> io::Result { 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.write_tag(Tag::Embedded)?; Ok(self.suspend()) } + #[inline(always)] fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> io::Result<()> { self.resume(ann); Ok(()) diff --git a/implementations/rust/preserves/src/value/reader.rs b/implementations/rust/preserves/src/value/reader.rs index 72d583c..b44647b 100644 --- a/implementations/rust/preserves/src/value/reader.rs +++ b/implementations/rust/preserves/src/value/reader.rs @@ -262,6 +262,7 @@ pub struct IOBinarySource { } impl IOBinarySource { + #[inline(always)] pub fn new(read: R) -> Self { IOBinarySource { read, buf: None } } @@ -270,22 +271,26 @@ impl IOBinarySource { impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource { type Mark = u64; + #[inline(always)] fn mark(&mut self) -> io::Result { 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 { match self.buf { Some(b) => Ok(b), @@ -303,6 +308,7 @@ impl<'de, R: io::Read + io::Seek> BinarySource<'de> for IOBinarySource { } } + #[inline(always)] fn readbytes(&mut self, count: usize) -> io::Result> { 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 { 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 { 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 { 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> { 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() { diff --git a/implementations/rust/preserves/src/value/repr.rs b/implementations/rust/preserves/src/value/repr.rs index 3db15e5..305569e 100644 --- a/implementations/rust/preserves/src/value/repr.rs +++ b/implementations/rust/preserves/src/value/repr.rs @@ -28,18 +28,22 @@ impl Domain for Arc {} pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord { type Embedded: Embeddable; + #[inline(always)] fn new(v: V) -> Self where Value: From { Value::from(v).wrap() } + #[inline(always)] fn domain(e: E) -> Self where Self::Embedded: From { Value::Embedded(e.into()).wrap() } + #[inline(always)] fn symbol(n: &str) -> Self { Value::symbol(n).wrap() } + #[inline(always)] fn bytestring<'a, V: Into>>(v: V) -> Self { Value::bytestring(v).wrap() } @@ -51,6 +55,7 @@ pub trait NestedValue: Sized + Debug + Clone + Eq + Hash + Ord { fn pieces(self) -> (Annotations, Value); fn value_owned(self) -> Value; + #[inline(always)] fn value_class(&self) -> ValueClass { self.value().value_class() } @@ -144,34 +149,42 @@ pub struct Double(pub f64); pub struct Record(pub Vec); impl Record { + #[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 { &self.0 } + #[inline(always)] pub fn fields_vec_mut(&mut self) -> &mut Vec { &mut self.0 } + #[inline(always)] pub fn finish(self) -> Value where N: NestedValue { Value::Record(self) } @@ -388,10 +401,12 @@ impl Value { 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 { if let Value::Boolean(b) = self { Some(*b) @@ -400,6 +415,7 @@ impl Value { } } + #[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 Value { } } + #[inline(always)] pub fn to_boolean(&self) -> Result { 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 Value { } } + #[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 Value { } } + #[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 { 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 { 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 Value { } } + #[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 Value { } } + #[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 { 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 { 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 Value { } } + #[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 Value { } } + #[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 { self.as_signedinteger().and_then(|n| n.try_into().ok()) } + #[inline(always)] pub fn to_i(&self) -> Result { 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 { self.as_signedinteger().and_then(|n| n.try_into().ok()) } + #[inline(always)] pub fn to_u(&self) -> Result { self.as_u().ok_or_else(|| self.expected(ExpectedKind::SignedIntegerU128)) } + #[inline(always)] pub fn as_u8(&self) -> Option { self.as_u().and_then(|i| i.to_u8()) } + #[inline(always)] pub fn as_i8(&self) -> Option { self.as_i().and_then(|i| i.to_i8()) } + #[inline(always)] pub fn as_u16(&self) -> Option { self.as_u().and_then(|i| i.to_u16()) } + #[inline(always)] pub fn as_i16(&self) -> Option { self.as_i().and_then(|i| i.to_i16()) } + #[inline(always)] pub fn as_u32(&self) -> Option { self.as_u().and_then(|i| i.to_u32()) } + #[inline(always)] pub fn as_i32(&self) -> Option { self.as_i().and_then(|i| i.to_i32()) } + #[inline(always)] pub fn as_u64(&self) -> Option { self.as_u().and_then(|i| i.to_u64()) } + #[inline(always)] pub fn as_i64(&self) -> Option { self.as_i().and_then(|i| i.to_i64()) } + #[inline(always)] pub fn as_u128(&self) -> Option { self.as_u().and_then(|i| i.to_u128()) } + #[inline(always)] pub fn as_i128(&self) -> Option { self.as_i().and_then(|i| i.to_i128()) } + #[inline(always)] pub fn as_usize(&self) -> Option { self.as_u().and_then(|i| i.to_usize()) } + #[inline(always)] pub fn as_isize(&self) -> Option { self.as_i().and_then(|i| i.to_isize()) } + #[inline(always)] pub fn to_i8(&self) -> Result { match self.as_i() { Some(i) => i.to_i8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -560,6 +616,7 @@ impl Value { } } + #[inline(always)] pub fn to_u8(&self) -> Result { match self.as_u() { Some(i) => i.to_u8().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -567,6 +624,7 @@ impl Value { } } + #[inline(always)] pub fn to_i16(&self) -> Result { match self.as_i() { Some(i) => i.to_i16().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -574,6 +632,7 @@ impl Value { } } + #[inline(always)] pub fn to_u16(&self) -> Result { match self.as_u() { Some(i) => i.to_u16().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -581,6 +640,7 @@ impl Value { } } + #[inline(always)] pub fn to_i32(&self) -> Result { match self.as_i() { Some(i) => i.to_i32().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -588,6 +648,7 @@ impl Value { } } + #[inline(always)] pub fn to_u32(&self) -> Result { match self.as_u() { Some(i) => i.to_u32().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -595,6 +656,7 @@ impl Value { } } + #[inline(always)] pub fn to_i64(&self) -> Result { match self.as_i() { Some(i) => i.to_i64().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -602,6 +664,7 @@ impl Value { } } + #[inline(always)] pub fn to_u64(&self) -> Result { match self.as_u() { Some(i) => i.to_u64().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -609,6 +672,7 @@ impl Value { } } + #[inline(always)] pub fn to_i128(&self) -> Result { match self.as_i() { Some(i) => i.to_i128().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -616,6 +680,7 @@ impl Value { } } + #[inline(always)] pub fn to_u128(&self) -> Result { match self.as_u() { Some(i) => i.to_u128().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -623,6 +688,7 @@ impl Value { } } + #[inline(always)] pub fn to_isize(&self) -> Result { match self.as_i() { Some(i) => i.to_isize().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -630,6 +696,7 @@ impl Value { } } + #[inline(always)] pub fn to_usize(&self) -> Result { match self.as_u() { Some(i) => i.to_usize().ok_or_else(|| Error::NumberOutOfRange(BigInt::from(i))), @@ -637,16 +704,19 @@ impl Value { } } + #[inline(always)] pub fn to_char(&self) -> Result { 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 Value { } } + #[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 Value { } } + #[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>>(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> { if let Value::ByteString(s) = self { Some(s) @@ -683,6 +758,7 @@ impl Value { } } + #[inline(always)] pub fn as_bytestring_mut(&mut self) -> Option<&mut Vec> { if let Value::ByteString(s) = self { Some(s) @@ -691,18 +767,22 @@ impl Value { } } + #[inline(always)] pub fn to_bytestring(&self) -> Result<&Vec, Error> { self.as_bytestring().ok_or_else(|| self.expected(ExpectedKind::ByteString)) } + #[inline(always)] pub fn symbol(s: &str) -> Value { 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 Value { } } + #[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 Value { } } + #[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 { 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) -> Option<&Record> { if let Value::Record(r) = self { match arity { @@ -745,6 +830,7 @@ impl Value { } } + #[inline(always)] pub fn into_record(self) -> Option> { match self { Value::Record(r) => Some(r), @@ -752,6 +838,7 @@ impl Value { } } + #[inline(always)] pub fn as_record_mut(&mut self, arity: Option) -> Option<&mut Record> { if let Value::Record(r) = self { match arity { @@ -764,28 +851,34 @@ impl Value { } } + #[inline(always)] pub fn to_record(&self, arity: Option) -> Result<&Record, 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 { Self::record(N::symbol(label), expected_arity) } + #[inline(always)] pub fn simple_record0(label: &str) -> Value { Self::simple_record(label, 0).finish() } + #[inline(always)] pub fn simple_record1(label: &str, field: N) -> Value { 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) -> bool { self.as_simple_record(label, arity).is_some() } + #[inline(always)] pub fn as_simple_record(&self, label: &str, arity: Option) -> Option<&[N]> { self.as_record(arity).and_then(|r| { match r.label().value() { @@ -795,6 +888,7 @@ impl Value { }) } + #[inline(always)] pub fn to_simple_record(&self, label: &str, arity: Option) -> Result<&[N], Error> { @@ -802,6 +896,7 @@ impl Value { .ok_or_else(|| self.expected(ExpectedKind::SimpleRecord(label.to_owned(), arity))) } + #[inline(always)] pub fn to_option(&self) -> Result, Error> { match self.as_simple_record("None", Some(0)) { Some(_fs) => Ok(None), @@ -812,10 +907,12 @@ impl Value { } } + #[inline(always)] pub fn is_sequence(&self) -> bool { self.as_sequence().is_some() } + #[inline(always)] pub fn as_sequence(&self) -> Option<&Vec> { if let Value::Sequence(s) = self { Some(s) @@ -824,6 +921,7 @@ impl Value { } } + #[inline(always)] pub fn into_sequence(self) -> Option> { match self { Value::Sequence(s) => Some(s), @@ -831,6 +929,7 @@ impl Value { } } + #[inline(always)] pub fn as_sequence_mut(&mut self) -> Option<&mut Vec> { if let Value::Sequence(s) = self { Some(s) @@ -839,14 +938,17 @@ impl Value { } } + #[inline(always)] pub fn to_sequence(&self) -> Result<&Vec, 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> { if let Value::Set(s) = self { Some(s) @@ -855,6 +957,7 @@ impl Value { } } + #[inline(always)] pub fn into_set(self) -> Option> { match self { Value::Set(s) => Some(s), @@ -862,6 +965,7 @@ impl Value { } } + #[inline(always)] pub fn as_set_mut(&mut self) -> Option<&mut Set> { if let Value::Set(s) = self { Some(s) @@ -870,14 +974,17 @@ impl Value { } } + #[inline(always)] pub fn to_set(&self) -> Result<&Set, 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> { if let Value::Dictionary(s) = self { Some(s) @@ -886,6 +993,7 @@ impl Value { } } + #[inline(always)] pub fn into_dictionary(self) -> Option> { match self { Value::Dictionary(s) => Some(s), @@ -893,6 +1001,7 @@ impl Value { } } + #[inline(always)] pub fn as_dictionary_mut(&mut self) -> Option<&mut Map> { if let Value::Dictionary(s) = self { Some(s) @@ -901,14 +1010,17 @@ impl Value { } } + #[inline(always)] pub fn to_dictionary(&self) -> Result<&Map, 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 Value { } } + #[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 Value { impl Index for Value { type Output = N; + #[inline(always)] fn index(&self, i: usize) -> &Self::Output { &self.as_sequence().unwrap()[i] } } impl IndexMut for Value { + #[inline(always)] fn index_mut(&mut self, i: usize) -> &mut Self::Output { &mut self.as_sequence_mut().unwrap()[i] } @@ -1009,6 +1124,7 @@ impl IndexMut for Value { impl Index<&N> for Value { 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(Option>>); impl Annotations { + #[inline(always)] pub fn empty() -> Self { Annotations(None) } + #[inline(always)] pub fn new(anns: Option>) -> 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 Annotations { } } + #[inline(always)] pub fn slice(&self) -> &[N] { self.maybe_slice().unwrap_or(&[]) } + #[inline(always)] pub fn to_vec(self) -> Vec { use std::ops::DerefMut; self.0.map(|mut b| std::mem::take(b.deref_mut())).unwrap_or_default() @@ -1101,12 +1222,14 @@ impl Annotations { pub struct AnnotatedValue(pub Annotations, pub Value); impl AnnotatedValue { + #[inline(always)] fn new(anns: Annotations, value: Value) -> Self { AnnotatedValue(anns, value) } } impl PartialEq for AnnotatedValue { + #[inline(always)] fn eq(&self, other: &Self) -> bool { self.1.eq(&other.1) } @@ -1115,18 +1238,21 @@ impl PartialEq for AnnotatedValue { impl Eq for AnnotatedValue {} impl Hash for AnnotatedValue { + #[inline(always)] fn hash(&self, state: &mut H) { self.1.hash(state); } } impl PartialOrd for AnnotatedValue { + #[inline(always)] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for AnnotatedValue { + #[inline(always)] fn cmp(&self, other: &Self) -> Ordering { self.1.cmp(&other.1) } @@ -1138,10 +1264,12 @@ impl Ord for AnnotatedValue { pub struct PlainValue(AnnotatedValue>); impl PlainValue { + #[inline(always)] pub fn annotations_mut(&mut self) -> &mut Annotations { &mut (self.0).0 } + #[inline(always)] pub fn value_mut(&mut self) -> &mut Value { &mut (self.0).1 } @@ -1150,23 +1278,28 @@ impl PlainValue { impl NestedValue for PlainValue { type Embedded = D; + #[inline(always)] fn wrap(anns: Annotations, v: Value) -> Self { PlainValue(AnnotatedValue::new(anns, v)) } + #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } + #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } + #[inline(always)] fn pieces(self) -> (Annotations, Value) { let AnnotatedValue(anns, v) = self.0; (anns, v) } + #[inline(always)] fn value_owned(self) -> Value { (self.0).1 } @@ -1188,18 +1321,22 @@ pub struct RcValue(Rc>>); impl NestedValue for RcValue { type Embedded = D; + #[inline(always)] fn wrap(anns: Annotations, v: Value) -> Self { RcValue(Rc::new(AnnotatedValue::new(anns, v))) } + #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } + #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } + #[inline(always)] fn pieces(self) -> (Annotations, Value) { match Rc::try_unwrap(self.0) { Ok(AnnotatedValue(anns, v)) => (anns, v), @@ -1207,6 +1344,7 @@ impl NestedValue for RcValue { } } + #[inline(always)] fn value_owned(self) -> Value { 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(Arc>>); impl NestedValue for ArcValue { type Embedded = D; + #[inline(always)] fn wrap(anns: Annotations, v: Value) -> Self { ArcValue(Arc::new(AnnotatedValue::new(anns, v))) } + #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } + #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } + #[inline(always)] fn pieces(self) -> (Annotations, Value) { match Arc::try_unwrap(self.0) { Ok(AnnotatedValue(anns, v)) => (anns, v), @@ -1245,6 +1387,7 @@ impl NestedValue for ArcValue { } } + #[inline(always)] fn value_owned(self) -> Value { 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, v: Value) -> Self { IOValue(Arc::new(AnnotatedValue::new(anns, v))) } + #[inline(always)] fn annotations(&self) -> &Annotations { &(self.0).0 } + #[inline(always)] fn value(&self) -> &Value { &(self.0).1 } + #[inline(always)] fn pieces(self) -> (Annotations, Value) { 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 { match Arc::try_unwrap(self.0) { Ok(AnnotatedValue(_anns, v)) => v, @@ -1324,6 +1472,7 @@ impl Debug for DummyValue { } impl DummyValue { + #[inline(always)] pub fn new() -> Self { DummyValue(AnnotatedValue::new(Annotations::empty(), Value::Boolean(false))) } @@ -1332,22 +1481,27 @@ impl DummyValue { impl NestedValue for DummyValue { type Embedded = D; + #[inline(always)] fn wrap(_anns: Annotations, _v: Value) -> Self { DummyValue::new() } + #[inline(always)] fn annotations(&self) -> &Annotations { &self.0.0 } + #[inline(always)] fn value(&self) -> &Value { &self.0.1 } + #[inline(always)] fn pieces(self) -> (Annotations, Value) { (self.0.0, self.0.1) } + #[inline(always)] fn value_owned(self) -> Value { self.0.1 } diff --git a/implementations/rust/preserves/src/value/suspendable.rs b/implementations/rust/preserves/src/value/suspendable.rs index 23dfdd0..42c9b71 100644 --- a/implementations/rust/preserves/src/value/suspendable.rs +++ b/implementations/rust/preserves/src/value/suspendable.rs @@ -10,6 +10,7 @@ impl Suspendable { 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 Suspendable { } } + #[inline(always)] pub fn resume(&mut self, other: Self) { match self { Suspendable::Suspended => @@ -31,6 +33,7 @@ impl Suspendable { } } + #[inline(always)] pub fn take(self) -> T { match self { Suspendable::Active(t) => t, @@ -42,6 +45,7 @@ impl Suspendable { impl Deref for Suspendable { type Target = T; + #[inline(always)] fn deref(&self) -> &Self::Target { match self { Suspendable::Suspended => panic!("Suspended Suspendable at deref"), @@ -51,6 +55,7 @@ impl Deref for Suspendable { } impl DerefMut for Suspendable { + #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { match self { Suspendable::Suspended => panic!("Empty Suspendable at deref_mut"),