Mercurial > hg
diff rust/hg-core/src/revlog/node.rs @ 46391:cfb6c10c08c2
rust: replace an unsafe use of transmute with a safe use of bytes-cast
Differential Revision: https://phab.mercurial-scm.org/D9859
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 25 Jan 2021 11:34:23 +0100 |
parents | 88e741bf2d93 |
children | 6380efb82191 |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/node.rs Fri Jan 15 16:11:54 2021 +0100 +++ b/rust/hg-core/src/revlog/node.rs Mon Jan 25 11:34:23 2021 +0100 @@ -8,8 +8,9 @@ //! In Mercurial code base, it is customary to call "a node" the binary SHA //! of a revision. +use bytes_cast::BytesCast; use hex::{self, FromHex, FromHexError}; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryFrom; /// The length in bytes of a `Node` /// @@ -49,7 +50,7 @@ /// /// [`nybbles_len`]: #method.nybbles_len /// [`ExactLengthRequired`]: struct.NodeError#variant.ExactLengthRequired -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, BytesCast)] #[repr(transparent)] pub struct Node { data: NodeData, @@ -68,14 +69,14 @@ /// Return an error if the slice has an unexpected length impl<'a> TryFrom<&'a [u8]> for &'a Node { - type Error = std::array::TryFromSliceError; + type Error = (); #[inline] fn try_from(bytes: &'a [u8]) -> Result<&'a Node, Self::Error> { - let data = bytes.try_into()?; - // Safety: `#[repr(transparent)]` makes it ok to "wrap" the target - // of a reference to the type of the single field. - Ok(unsafe { std::mem::transmute::<&NodeData, &Node>(data) }) + match Node::from_bytes(bytes) { + Ok((node, rest)) if rest.is_empty() => Ok(node), + _ => Err(()), + } } }