diff --git a/src/arena.rs b/src/arena.rs index 4fc3e42..9124ab2 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -5,6 +5,7 @@ use alloc::vec::Vec; #[cfg(not(feature = "std"))] use core::{ + mem, num::NonZeroUsize, ops::{Index, IndexMut}, }; @@ -17,6 +18,7 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "std")] use std::{ + mem, num::NonZeroUsize, ops::{Index, IndexMut}, }; @@ -79,18 +81,20 @@ impl Arena { /// assert_eq!(*arena[node_id].get(), "foo"); /// ``` pub fn get_node_id(&self, node: &Node) -> Option { - // self.nodes.as_ptr_range() is not stable until rust 1.48 - let start = self.nodes.as_ptr() as usize; - let end = start + self.nodes.len() * core::mem::size_of::>(); - let p = node as *const Node as usize; - if (start..end).contains(&p) { - let node_id = (p - start) / core::mem::size_of::>(); - NonZeroUsize::new(node_id.wrapping_add(1)).map(|node_id_non_zero| { - NodeId::from_non_zero_usize(node_id_non_zero, self.nodes[node_id].stamp) - }) - } else { - None + let nodes_range = self.nodes.as_ptr_range(); + let p = node as *const Node; + + if !nodes_range.contains(&p) { + return None; } + + let node_index = (p as usize - nodes_range.start as usize) / mem::size_of::>(); + let node_id = NonZeroUsize::new(node_index.wrapping_add(1))?; + + Some(NodeId::from_non_zero_usize( + node_id, + self.nodes[node_index].stamp, + )) } /// Retrieves the `NodeId` corresponding to the `Node` at `index` in the `Arena`, if it exists.