use std;
use std::mem;
use std::ffi::{OsStr, OsString};
use super::platform;
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WideString {
inner: Vec<u16>,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct WideStr {
inner: [u16],
}
impl WideString {
pub fn new() -> WideString {
WideString { inner: vec![] }
}
pub fn from_vec<T: Into<Vec<u16>>>(raw: T) -> WideString {
WideString { inner: raw.into() }
}
pub fn from_str<S: AsRef<OsStr> + ?Sized>(s: &S) -> WideString {
WideString {
inner: platform::os_to_wide(s.as_ref()),
}
}
pub unsafe fn from_ptr(p: *const u16, len: usize) -> WideString {
if len == 0 {
return WideString::new();
}
assert!(!p.is_null());
let slice = std::slice::from_raw_parts(p, len);
WideString::from_vec(slice)
}
pub fn with_capacity(capacity: usize) -> WideString {
WideString {
inner: Vec::with_capacity(capacity),
}
}
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
pub fn clear(&mut self) {
self.inner.clear()
}
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional)
}
pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional)
}
pub fn as_wide_str(&self) -> &WideStr {
self
}
pub fn into_vec(self) -> Vec<u16> {
self.inner
}
pub fn push<T: AsRef<WideStr>>(&mut self, s: T) {
self.inner.extend_from_slice(&s.as_ref().inner)
}
pub fn push_slice<T: AsRef<[u16]>>(&mut self, s: T) {
self.inner.extend_from_slice(&s.as_ref())
}
pub fn push_str<T: AsRef<OsStr>>(&mut self, s: T) {
self.inner.extend(platform::os_to_wide(s.as_ref()))
}
pub fn shrink_to_fit(&mut self) {
self.inner.shrink_to_fit();
}
pub fn into_boxed_wide_str(self) -> Box<WideStr> {
let rw = Box::into_raw(self.inner.into_boxed_slice()) as *mut WideStr;
unsafe { Box::from_raw(rw) }
}
}
impl Into<Vec<u16>> for WideString {
fn into(self) -> Vec<u16> {
self.into_vec()
}
}
impl<'a> From<WideString> for std::borrow::Cow<'a, WideStr> {
fn from(s: WideString) -> std::borrow::Cow<'a, WideStr> {
std::borrow::Cow::Owned(s)
}
}
impl From<String> for WideString {
fn from(s: String) -> WideString {
WideString::from_str(&s)
}
}
impl From<OsString> for WideString {
fn from(s: OsString) -> WideString {
WideString::from_str(&s)
}
}
impl From<WideString> for OsString {
fn from(s: WideString) -> OsString {
s.to_os_string()
}
}
impl<'a, T: ?Sized + AsRef<WideStr>> From<&'a T> for WideString {
fn from(s: &'a T) -> WideString {
s.as_ref().to_wide_string()
}
}
impl std::ops::Index<std::ops::RangeFull> for WideString {
type Output = WideStr;
#[inline]
fn index(&self, _index: std::ops::RangeFull) -> &WideStr {
WideStr::from_slice(&self.inner)
}
}
impl std::ops::Deref for WideString {
type Target = WideStr;
#[inline]
fn deref(&self) -> &WideStr {
&self[..]
}
}
impl PartialEq<WideStr> for WideString {
#[inline]
fn eq(&self, other: &WideStr) -> bool {
self.as_wide_str() == other
}
}
impl PartialOrd<WideStr> for WideString {
#[inline]
fn partial_cmp(&self, other: &WideStr) -> Option<std::cmp::Ordering> {
self.as_wide_str().partial_cmp(other)
}
}
impl<'a> PartialEq<&'a WideStr> for WideString {
#[inline]
fn eq(&self, other: &&'a WideStr) -> bool {
self.as_wide_str() == *other
}
}
impl<'a> PartialOrd<&'a WideStr> for WideString {
#[inline]
fn partial_cmp(&self, other: &&'a WideStr) -> Option<std::cmp::Ordering> {
self.as_wide_str().partial_cmp(*other)
}
}
impl<'a> PartialEq<std::borrow::Cow<'a, WideStr>> for WideString {
#[inline]
fn eq(&self, other: &std::borrow::Cow<'a, WideStr>) -> bool {
self.as_wide_str() == other.as_ref()
}
}
impl<'a> PartialOrd<std::borrow::Cow<'a, WideStr>> for WideString {
#[inline]
fn partial_cmp(&self, other: &std::borrow::Cow<'a, WideStr>) -> Option<std::cmp::Ordering> {
self.as_wide_str().partial_cmp(other.as_ref())
}
}
impl WideStr {
pub fn new<'a, S: AsRef<WideStr> + ?Sized>(s: &'a S) -> &'a WideStr {
s.as_ref()
}
pub unsafe fn from_ptr<'a>(p: *const u16, len: usize) -> &'a WideStr {
assert!(!p.is_null());
mem::transmute(std::slice::from_raw_parts(p, len))
}
pub fn from_slice<'a>(slice: &'a [u16]) -> &'a WideStr {
unsafe { mem::transmute(slice) }
}
pub fn to_os_string(&self) -> OsString {
platform::os_from_wide(&self.inner)
}
pub fn to_wide_string(&self) -> WideString {
WideString::from_vec(&self.inner)
}
pub fn to_string(&self) -> Result<String, std::string::FromUtf16Error> {
String::from_utf16(&self.inner)
}
pub fn to_string_lossy(&self) -> String {
String::from_utf16_lossy(&self.inner)
}
pub fn as_slice(&self) -> &[u16] {
&self.inner
}
pub fn as_ptr(&self) -> *const u16 {
self.inner.as_ptr()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn into_wide_string(self: Box<WideStr>) -> WideString {
let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut [u16]) };
WideString {
inner: boxed.into_vec(),
}
}
}
impl std::borrow::Borrow<WideStr> for WideString {
fn borrow(&self) -> &WideStr {
&self[..]
}
}
impl ToOwned for WideStr {
type Owned = WideString;
fn to_owned(&self) -> WideString {
self.to_wide_string()
}
}
impl<'a> From<&'a WideStr> for std::borrow::Cow<'a, WideStr> {
fn from(s: &'a WideStr) -> std::borrow::Cow<'a, WideStr> {
std::borrow::Cow::Borrowed(s)
}
}
impl AsRef<WideStr> for WideStr {
fn as_ref(&self) -> &WideStr {
self
}
}
impl AsRef<WideStr> for WideString {
fn as_ref(&self) -> &WideStr {
self
}
}
impl AsRef<[u16]> for WideStr {
fn as_ref(&self) -> &[u16] {
self.as_slice()
}
}
impl AsRef<[u16]> for WideString {
fn as_ref(&self) -> &[u16] {
self.as_slice()
}
}
impl<'a> From<&'a WideStr> for Box<WideStr> {
fn from(s: &'a WideStr) -> Box<WideStr> {
let boxed: Box<[u16]> = Box::from(&s.inner);
let rw = Box::into_raw(boxed) as *mut WideStr;
unsafe { Box::from_raw(rw) }
}
}
impl From<Box<WideStr>> for WideString {
fn from(boxed: Box<WideStr>) -> WideString {
boxed.into_wide_string()
}
}
impl From<WideString> for Box<WideStr> {
fn from(s: WideString) -> Box<WideStr> {
s.into_boxed_wide_str()
}
}
impl Default for Box<WideStr> {
fn default() -> Box<WideStr> {
let boxed: Box<[u16]> = Box::from([]);
let rw = Box::into_raw(boxed) as *mut WideStr;
unsafe { Box::from_raw(rw) }
}
}