From 1b43c6bc2bed607afd3d06423826b96951097dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20S=C3=A1=20de=20Mello?= Date: Tue, 15 Oct 2024 00:51:15 +0100 Subject: [PATCH 1/5] boxing --- src/pointer.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/pointer.rs b/src/pointer.rs index 120534b..ff2a5ba 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -515,6 +515,14 @@ impl Pointer { pub fn is_empty(&self) -> bool { self.0.is_empty() } + + /// Converts a `Box` into a `PointerBuf` without copying or allocating. + pub fn into_buf(self: Box) -> PointerBuf { + let inner = Box::into_raw(self); + // SAFETY: we ensure the layout of `Pointer` is the same as `str` + let inner = unsafe { Box::::from_raw(inner as *mut str) }; + PointerBuf(inner.into_string()) + } } #[cfg(feature = "serde")] @@ -943,6 +951,14 @@ impl Deref for PointerBuf { } } +impl From for Box { + fn from(value: PointerBuf) -> Self { + let s = value.0.into_boxed_str(); + // SAFETY> we ensure that the layout of `str` is the same as `Pointer` + unsafe { Box::from_raw(Box::into_raw(s) as *mut Pointer) } + } +} + #[cfg(feature = "serde")] impl<'de> serde::Deserialize<'de> for PointerBuf { fn deserialize(deserializer: D) -> Result @@ -2135,4 +2151,12 @@ mod tests { let borrowed: &Pointer = ptr.borrow(); assert_eq!(borrowed, "/foo/bar"); } + + #[test] + fn from_box_to_buf() { + let original = PointerBuf::parse("/foo/bar/0").unwrap(); + let boxed: Box = original.clone().into(); + let unboxed = boxed.into_buf(); + assert_eq!(original, unboxed); + } } From 0c3feee16fb402358bdc450f7733ce5ab6c49e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20S=C3=A1=20de=20Mello?= Date: Tue, 15 Oct 2024 00:57:02 +0100 Subject: [PATCH 2/5] add changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5306efd..ffe7968 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# [Unreleased] + +- Adds method `into_buf` for `Box` and `impl From for Box`. + ## [0.6.2] 2024-09-30 ### Added From 9a4e4c116a91dd893812334c530401b079c08c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20S=C3=A1=20de=20Mello?= Date: Tue, 15 Oct 2024 01:00:51 +0100 Subject: [PATCH 3/5] tweak changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffe7968..a37116c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # [Unreleased] +### Added + - Adds method `into_buf` for `Box` and `impl From for Box`. ## [0.6.2] 2024-09-30 From 4230a100f9a3d108f634623afe13150cd4be15d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20S=C3=A1=20de=20Mello?= Date: Tue, 15 Oct 2024 01:03:41 +0100 Subject: [PATCH 4/5] import Box explicitly --- src/pointer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pointer.rs b/src/pointer.rs index ff2a5ba..084096a 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -1,6 +1,7 @@ use crate::{token::InvalidEncodingError, Components, Token, Tokens}; use alloc::{ borrow::ToOwned, + boxed::Box, fmt, string::{String, ToString}, vec::Vec, From e7045865107f2371825b5147c7389969f04bfe8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Mello?= <3285133+asmello@users.noreply.github.com> Date: Tue, 15 Oct 2024 21:36:02 +0100 Subject: [PATCH 5/5] fix typo --- src/pointer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pointer.rs b/src/pointer.rs index 903a937..256402c 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -952,7 +952,7 @@ impl Deref for PointerBuf { impl From for Box { fn from(value: PointerBuf) -> Self { let s = value.0.into_boxed_str(); - // SAFETY> we ensure that the layout of `str` is the same as `Pointer` + // SAFETY: we ensure that the layout of `str` is the same as `Pointer` unsafe { Box::from_raw(Box::into_raw(s) as *mut Pointer) } } }