servo/components/style_traits/owned_str.rs
author Emilio Cobos Álvarez <emilio@crisal.io>
Thu, 16 May 2019 23:04:31 +0000
changeset 533073 1e32fe8538eddbf6b87bb2dccb716f425d8dd931
parent 532916 b28a48e2ed212dc5dea20ddab26e37f66b00a2c0
child 535196 f14b602c5ee7cec1981b4ce2aa06e0581c3467e8
permissions -rw-r--r--
Bug 1550554 - Use ArcSlice for quotes. r=heycam This saves the intermediate allocation. Differential Revision: https://phabricator.services.mozilla.com/D30546

/* 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(Default, Clone, PartialEq, Eq, MallocSizeOf, 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 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())
    }
}