diff --git a/rust/flatbuffers/src/builder.rs b/rust/flatbuffers/src/builder.rs index 36d6c6a7e..0b20f9eee 100644 --- a/rust/flatbuffers/src/builder.rs +++ b/rust/flatbuffers/src/builder.rs @@ -389,10 +389,7 @@ impl<'fbb> FlatBufferBuilder<'fbb> { #[inline] fn track_field(&mut self, slot_off: VOffsetT, off: UOffsetT) { - let fl = FieldLoc { - id: slot_off, - off: off, - }; + let fl = FieldLoc { id: slot_off, off }; self.field_locs.push(fl); } @@ -406,7 +403,7 @@ impl<'fbb> FlatBufferBuilder<'fbb> { // Write the vtable offset, which is the start of any Table. // We fill its value later. let object_revloc_to_vtable: WIPOffset = - WIPOffset::new(self.push::(0xF0F0F0F0 as UOffsetT).value()); + WIPOffset::new(self.push::(0xF0F0_F0F0 as UOffsetT).value()); // Layout of the data this function will create when a new vtable is // needed. @@ -496,7 +493,7 @@ impl<'fbb> FlatBufferBuilder<'fbb> { { let n = self.head + self.used_space() - object_revloc_to_vtable.value() as usize; let saw = read_scalar_at::(&self.owned_buf, n); - debug_assert_eq!(saw, 0xF0F0F0F0); + debug_assert_eq!(saw, 0xF0F0_F0F0); emplace_scalar::( &mut self.owned_buf[n..n + SIZE_SOFFSET], vt_use as SOffsetT - object_revloc_to_vtable.value() as SOffsetT, @@ -619,7 +616,7 @@ impl<'fbb> FlatBufferBuilder<'fbb> { #[inline] fn push_bytes_unprefixed(&mut self, x: &[u8]) -> UOffsetT { let n = self.make_space(x.len()); - &mut self.owned_buf[n..n + x.len()].copy_from_slice(x); + self.owned_buf[n..n + x.len()].copy_from_slice(x); n as UOffsetT } diff --git a/rust/flatbuffers/src/primitives.rs b/rust/flatbuffers/src/primitives.rs index cfd414048..2f3b7421e 100644 --- a/rust/flatbuffers/src/primitives.rs +++ b/rust/flatbuffers/src/primitives.rs @@ -60,33 +60,28 @@ pub type UOffsetT = u32; pub type VOffsetT = i16; /// TableFinishedWIPOffset marks a WIPOffset as being for a finished table. +#[derive(Clone, Copy)] pub struct TableFinishedWIPOffset {} /// TableUnfinishedWIPOffset marks a WIPOffset as being for an unfinished table. +#[derive(Clone, Copy)] pub struct TableUnfinishedWIPOffset {} /// UnionWIPOffset marks a WIPOffset as being for a union value. +#[derive(Clone, Copy)] pub struct UnionWIPOffset {} /// VTableWIPOffset marks a WIPOffset as being for a vtable. +#[derive(Clone, Copy)] pub struct VTableWIPOffset {} /// WIPOffset contains an UOffsetT with a special meaning: it is the location of /// data relative to the *end* of an in-progress FlatBuffer. The /// FlatBufferBuilder uses this to track the location of objects in an absolute /// way. The impl of Push converts a WIPOffset into a ForwardsUOffset. -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct WIPOffset(UOffsetT, PhantomData); -// TODO(rw): why do we need to reimplement (with a default impl) Copy to -// avoid ownership errors? -impl Copy for WIPOffset {} -impl Clone for WIPOffset { - #[inline] - fn clone(&self) -> WIPOffset { - WIPOffset::new(self.0.clone()) - } -} impl PartialEq for WIPOffset { fn eq(&self, o: &WIPOffset) -> bool { self.value() == o.value() @@ -144,7 +139,7 @@ impl Push for ForwardsUOffset { /// ForwardsUOffset is used by Follow to traverse a FlatBuffer: the pointer /// is incremented by the value contained in this type. -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct ForwardsUOffset(UOffsetT, PhantomData); impl ForwardsUOffset { #[inline(always)] diff --git a/rust/flatbuffers/src/table.rs b/rust/flatbuffers/src/table.rs index 7b1c4a542..397d24c6d 100644 --- a/rust/flatbuffers/src/table.rs +++ b/rust/flatbuffers/src/table.rs @@ -27,7 +27,7 @@ pub struct Table<'a> { impl<'a> Table<'a> { #[inline] pub fn new(buf: &'a [u8], loc: usize) -> Self { - Table { buf: buf, loc: loc } + Table { buf, loc } } #[inline] pub fn vtable(&self) -> VTable<'a> { @@ -51,7 +51,7 @@ impl<'a> Follow<'a> for Table<'a> { type Inner = Table<'a>; #[inline] fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Table { buf: buf, loc: loc } + Table { buf, loc } } } diff --git a/rust/flatbuffers/src/vector.rs b/rust/flatbuffers/src/vector.rs index 66653ebe4..de97abb4f 100644 --- a/rust/flatbuffers/src/vector.rs +++ b/rust/flatbuffers/src/vector.rs @@ -25,7 +25,7 @@ use endian_scalar::{read_scalar, read_scalar_at}; use follow::Follow; use primitives::*; -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData); impl<'a, T: 'a> Vector<'a, T> { @@ -42,6 +42,10 @@ impl<'a, T: 'a> Vector<'a, T> { pub fn len(&self) -> usize { read_scalar::(&self.0[self.1 as usize..]) as usize } + #[inline(always)] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } } impl<'a, T: Follow<'a> + 'a> Vector<'a, T> { @@ -102,8 +106,7 @@ impl<'a> Follow<'a> for &'a str { fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { let len = read_scalar_at::(&buf, loc) as usize; let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]; - let s = unsafe { from_utf8_unchecked(slice) }; - s + unsafe { from_utf8_unchecked(slice) } } } diff --git a/rust/flatbuffers/src/vtable.rs b/rust/flatbuffers/src/vtable.rs index 580867039..f8f266a07 100644 --- a/rust/flatbuffers/src/vtable.rs +++ b/rust/flatbuffers/src/vtable.rs @@ -34,7 +34,7 @@ impl<'a> PartialEq for VTable<'a> { impl<'a> VTable<'a> { pub fn init(buf: &'a [u8], loc: usize) -> Self { - VTable { buf: buf, loc: loc } + VTable { buf, loc } } pub fn num_fields(&self) -> usize { (self.num_bytes() / SIZE_VOFFSET) - 2 diff --git a/rust/flatbuffers/src/vtable_writer.rs b/rust/flatbuffers/src/vtable_writer.rs index d1e87dde2..f065fdd05 100644 --- a/rust/flatbuffers/src/vtable_writer.rs +++ b/rust/flatbuffers/src/vtable_writer.rs @@ -28,7 +28,7 @@ pub struct VTableWriter<'a> { impl<'a> VTableWriter<'a> { #[inline(always)] pub fn init(buf: &'a mut [u8]) -> Self { - VTableWriter { buf: buf } + VTableWriter { buf } } /// Writes the vtable length (in bytes) into the vtable. diff --git a/tests/rust_usage_test/bin/alloc_check.rs b/tests/rust_usage_test/bin/alloc_check.rs index ae1039cb1..e7ec9e5bc 100644 --- a/tests/rust_usage_test/bin/alloc_check.rs +++ b/tests/rust_usage_test/bin/alloc_check.rs @@ -106,10 +106,13 @@ fn main() { assert_eq!("MyMonster", m.name()); let pos = m.pos().unwrap(); - assert_eq!(pos.x(), 1.0f32); - assert_eq!(pos.y(), 2.0f32); - assert_eq!(pos.z(), 3.0f32); - assert_eq!(pos.test1(), 3.0f64); + // We know the bits should be exactly equal here but compilers may + // optimize floats in subtle ways so we're playing it safe and using + // epsilon comparison + assert!((pos.x() - 1.0f32).abs() < std::f32::EPSILON); + assert!((pos.y() - 2.0f32).abs() < std::f32::EPSILON); + assert!((pos.z() - 3.0f32).abs() < std::f32::EPSILON); + assert!((pos.test1() - 3.0f64).abs() < std::f64::EPSILON); assert_eq!(pos.test2(), my_game::example::Color::Green); let pos_test3 = pos.test3(); assert_eq!(pos_test3.a(), 5i16); @@ -126,8 +129,8 @@ fn main() { let test4 = m.test4().unwrap(); assert_eq!(test4.len(), 2); - assert_eq!(test4[0].a() as i32 + test4[0].b() as i32 + - test4[1].a() as i32 + test4[1].b() as i32, 100); + assert_eq!(i32::from(test4[0].a()) + i32::from(test4[1].a()) + + i32::from(test4[0].b()) + i32::from(test4[1].b()), 100); let testarrayofstring = m.testarrayofstring().unwrap(); assert_eq!(testarrayofstring.len(), 2);