Skip to content

Commit

Permalink
Synchronize platform adaptors for OsString/OsStr
Browse files Browse the repository at this point in the history
* Order items as the average of the two adaptors. Enables easier diffs.
* Consistently apply #[inline].
* Implement FromInner<Vec<u8>> for bytes::Buf.
* Implement Clone::clone_from for wtf8::Buf.
  • Loading branch information
thaliaarchi authored and gitbot committed Mar 3, 2025
1 parent 4370aaa commit d3c07ff
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 74 deletions.
86 changes: 50 additions & 36 deletions std/src/sys/os_str/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::collections::TryReserveError;
use crate::fmt::Write;
use crate::rc::Rc;
use crate::sync::Arc;
use crate::sys_common::{AsInner, IntoInner};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::{fmt, mem, str};

#[cfg(test)]
Expand All @@ -25,6 +25,37 @@ pub struct Slice {
pub inner: [u8],
}

impl IntoInner<Vec<u8>> for Buf {
fn into_inner(self) -> Vec<u8> {
self.inner
}
}

impl FromInner<Vec<u8>> for Buf {
fn from_inner(inner: Vec<u8>) -> Self {
Buf { inner }
}
}

impl AsInner<[u8]> for Buf {
#[inline]
fn as_inner(&self) -> &[u8] {
&self.inner
}
}

impl fmt::Debug for Buf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), f)
}
}

impl fmt::Display for Buf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), f)
}
}

impl fmt::Debug for Slice {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner.utf8_chunks().debug(), f)
Expand Down Expand Up @@ -55,18 +86,6 @@ impl fmt::Display for Slice {
}
}

impl fmt::Debug for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), formatter)
}
}

impl fmt::Display for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), formatter)
}
}

impl Clone for Buf {
#[inline]
fn clone(&self) -> Self {
Expand All @@ -79,19 +98,6 @@ impl Clone for Buf {
}
}

impl IntoInner<Vec<u8>> for Buf {
fn into_inner(self) -> Vec<u8> {
self.inner
}
}

impl AsInner<[u8]> for Buf {
#[inline]
fn as_inner(&self) -> &[u8] {
&self.inner
}
}

impl Buf {
#[inline]
pub fn into_encoded_bytes(self) -> Vec<u8> {
Expand All @@ -103,6 +109,12 @@ impl Buf {
Self { inner: s }
}

#[inline]
pub fn into_string(self) -> Result<String, Buf> {
String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
}

#[inline]
pub fn from_string(s: String) -> Buf {
Buf { inner: s.into_bytes() }
}
Expand All @@ -122,6 +134,11 @@ impl Buf {
self.inner.capacity()
}

#[inline]
pub fn push_slice(&mut self, s: &Slice) {
self.inner.extend_from_slice(&s.inner)
}

#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
Expand Down Expand Up @@ -157,23 +174,15 @@ impl Buf {
// SAFETY: Slice just wraps [u8],
// and &*self.inner is &[u8], therefore
// transmuting &[u8] to &Slice is safe.
unsafe { mem::transmute(&*self.inner) }
unsafe { mem::transmute(self.inner.as_slice()) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut Slice {
// SAFETY: Slice just wraps [u8],
// and &mut *self.inner is &mut [u8], therefore
// transmuting &mut [u8] to &mut Slice is safe.
unsafe { mem::transmute(&mut *self.inner) }
}

pub fn into_string(self) -> Result<String, Buf> {
String::from_utf8(self.inner).map_err(|p| Buf { inner: p.into_bytes() })
}

pub fn push_slice(&mut self, s: &Slice) {
self.inner.extend_from_slice(&s.inner)
unsafe { mem::transmute(self.inner.as_mut_slice()) }
}

#[inline]
Expand Down Expand Up @@ -278,18 +287,22 @@ impl Slice {
unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) }
}

#[inline]
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
str::from_utf8(&self.inner)
}

#[inline]
pub fn to_string_lossy(&self) -> Cow<'_, str> {
String::from_utf8_lossy(&self.inner)
}

#[inline]
pub fn to_owned(&self) -> Buf {
Buf { inner: self.inner.to_vec() }
}

#[inline]
pub fn clone_into(&self, buf: &mut Buf) {
self.inner.clone_into(&mut buf.inner)
}
Expand All @@ -300,6 +313,7 @@ impl Slice {
unsafe { mem::transmute(boxed) }
}

#[inline]
pub fn empty_box() -> Box<Slice> {
let boxed: Box<[u8]> = Default::default();
unsafe { mem::transmute(boxed) }
Expand Down
107 changes: 69 additions & 38 deletions std/src/sys/os_str/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ use crate::sys_common::wtf8::{Wtf8, Wtf8Buf, check_utf8_boundary};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::{fmt, mem};

#[derive(Clone, Hash)]
#[derive(Hash)]
pub struct Buf {
pub inner: Wtf8Buf,
}

#[repr(transparent)]
pub struct Slice {
pub inner: Wtf8,
}

impl IntoInner<Wtf8Buf> for Buf {
fn into_inner(self) -> Wtf8Buf {
self.inner
Expand All @@ -35,31 +40,38 @@ impl AsInner<Wtf8> for Buf {
}

impl fmt::Debug for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.as_slice(), f)
}
}

impl fmt::Display for Buf {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.as_slice(), f)
}
}

#[repr(transparent)]
pub struct Slice {
pub inner: Wtf8,
}

impl fmt::Debug for Slice {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner, formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner, f)
}
}

impl fmt::Display for Slice {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.inner, formatter)
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.inner, f)
}
}

impl Clone for Buf {
#[inline]
fn clone(&self) -> Self {
Buf { inner: self.inner.clone() }
}

#[inline]
fn clone_from(&mut self, source: &Self) {
self.inner.clone_from(&source.inner)
}
}

Expand All @@ -74,62 +86,57 @@ impl Buf {
unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } }
}

pub fn with_capacity(capacity: usize) -> Buf {
Buf { inner: Wtf8Buf::with_capacity(capacity) }
}

pub fn clear(&mut self) {
self.inner.clear()
}

pub fn capacity(&self) -> usize {
self.inner.capacity()
#[inline]
pub fn into_string(self) -> Result<String, Buf> {
self.inner.into_string().map_err(|buf| Buf { inner: buf })
}

#[inline]
pub fn from_string(s: String) -> Buf {
Buf { inner: Wtf8Buf::from_string(s) }
}

pub fn as_slice(&self) -> &Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_slice() returns &Wtf8.
// Therefore, transmuting &Wtf8 to &Slice is safe.
unsafe { mem::transmute(self.inner.as_slice()) }
#[inline]
pub fn with_capacity(capacity: usize) -> Buf {
Buf { inner: Wtf8Buf::with_capacity(capacity) }
}

pub fn as_mut_slice(&mut self) -> &mut Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_mut_slice() returns &mut Wtf8.
// Therefore, transmuting &mut Wtf8 to &mut Slice is safe.
// Additionally, care should be taken to ensure the slice
// is always valid Wtf8.
unsafe { mem::transmute(self.inner.as_mut_slice()) }
#[inline]
pub fn clear(&mut self) {
self.inner.clear()
}

pub fn into_string(self) -> Result<String, Buf> {
self.inner.into_string().map_err(|buf| Buf { inner: buf })
#[inline]
pub fn capacity(&self) -> usize {
self.inner.capacity()
}

#[inline]
pub fn push_slice(&mut self, s: &Slice) {
self.inner.push_wtf8(&s.inner)
}

#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
}

#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.inner.try_reserve(additional)
}

#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional)
}

#[inline]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.inner.try_reserve_exact(additional)
}

#[inline]
pub fn shrink_to_fit(&mut self) {
self.inner.shrink_to_fit()
}
Expand All @@ -139,6 +146,24 @@ impl Buf {
self.inner.shrink_to(min_capacity)
}

#[inline]
pub fn as_slice(&self) -> &Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_slice() returns &Wtf8.
// Therefore, transmuting &Wtf8 to &Slice is safe.
unsafe { mem::transmute(self.inner.as_slice()) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut Slice {
// SAFETY: Slice is just a wrapper for Wtf8,
// and self.inner.as_mut_slice() returns &mut Wtf8.
// Therefore, transmuting &mut Wtf8 to &mut Slice is safe.
// Additionally, care should be taken to ensure the slice
// is always valid Wtf8.
unsafe { mem::transmute(self.inner.as_mut_slice()) }
}

#[inline]
pub fn leak<'a>(self) -> &'a mut Slice {
unsafe { mem::transmute(self.inner.leak()) }
Expand Down Expand Up @@ -194,6 +219,7 @@ impl Slice {
}

#[track_caller]
#[inline]
pub fn check_public_boundary(&self, index: usize) {
check_utf8_boundary(&self.inner, index);
}
Expand All @@ -203,18 +229,22 @@ impl Slice {
unsafe { mem::transmute(Wtf8::from_str(s)) }
}

#[inline]
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
self.inner.as_str()
}

#[inline]
pub fn to_string_lossy(&self) -> Cow<'_, str> {
self.inner.to_string_lossy()
}

#[inline]
pub fn to_owned(&self) -> Buf {
Buf { inner: self.inner.to_owned() }
}

#[inline]
pub fn clone_into(&self, buf: &mut Buf) {
self.inner.clone_into(&mut buf.inner)
}
Expand All @@ -224,6 +254,7 @@ impl Slice {
unsafe { mem::transmute(self.inner.into_box()) }
}

#[inline]
pub fn empty_box() -> Box<Slice> {
unsafe { mem::transmute(Wtf8::empty_box()) }
}
Expand Down

0 comments on commit d3c07ff

Please sign in to comment.