blob: ebfdcd5e06656da056982885419861c49b808663 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#![allow(unsafe_code)]
//! A replacement for `Box<str>` that has a defined layout for FFI.
use crate::owned_slice::OwnedSlice;
use std::fmt;
use std::ops::{Deref, DerefMut};
/// A struct that basically replaces a Box<str>, but with a defined layout,
/// suitable for FFI.
#[repr(C)]
#[derive(Clone, Default, Eq, MallocSizeOf, PartialEq, ToShmem)]
pub struct OwnedStr(OwnedSlice<u8>);
impl fmt::Debug for OwnedStr {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
self.deref().fmt(formatter)
}
}
impl Deref for OwnedStr {
type Target = str;
#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { std::str::from_utf8_unchecked(&*self.0) }
}
}
impl DerefMut for OwnedStr {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { std::str::from_utf8_unchecked_mut(&mut *self.0) }
}
}
impl OwnedStr {
/// Convert the OwnedStr into a boxed str.
#[inline]
pub fn into_box(self) -> Box<str> {
self.into_string().into_boxed_str()
}
/// Convert the OwnedStr into a `String`.
#[inline]
pub fn into_string(self) -> String {
unsafe { String::from_utf8_unchecked(self.0.into_vec()) }
}
}
impl From<OwnedStr> for String {
#[inline]
fn from(b: OwnedStr) -> Self {
b.into_string()
}
}
impl From<OwnedStr> for Box<str> {
#[inline]
fn from(b: OwnedStr) -> Self {
b.into_box()
}
}
impl From<Box<str>> for OwnedStr {
#[inline]
fn from(b: Box<str>) -> Self {
Self::from(b.into_string())
}
}
impl From<String> for OwnedStr {
#[inline]
fn from(s: String) -> Self {
OwnedStr(s.into_bytes().into())
}
}
|