diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 2db5b3e..0c496bc 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -12,6 +12,12 @@ - Adapt to latest cimgui API changes - Bump minimum Rust version to 1.20 - Upgrade to bitflags 1.0 +- Various minor ImString/ImStr changes +- `text` now accepts normal Rust strings. ImStr is still needed everywhere else + +### Fixed + +- Default impl for ImString was incorrect and could cause a crash ### Deprecated @@ -21,6 +27,10 @@ - `color_edit3`. Use `color_edit` instead - `color_edit4`. Use `color_edit` instead +### Removed + +- ImStr -> str Deref. Use `to_str` instead. + ## [0.0.16] - 2017-10-26 ### Added diff --git a/src/lib.rs b/src/lib.rs index 4c49bfc..d87881b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -468,7 +468,7 @@ impl<'ui> Ui<'ui> { // Widgets impl<'ui> Ui<'ui> { - pub fn text>(&self, text: P) { + pub fn text>(&self, text: S) { let s = text.as_ref(); unsafe { let start = s.as_ptr(); diff --git a/src/string.rs b/src/string.rs index f6c78e6..f78799c 100644 --- a/src/string.rs +++ b/src/string.rs @@ -2,11 +2,11 @@ use std::borrow::Borrow; use std::ffi::CStr; use std::fmt; use std::mem; -use std::ops::Deref; +use std::ops::{Deref, Index, RangeFull}; use std::os::raw::c_char; use std::str; -#[derive(Clone, Default, Hash, Ord, Eq, PartialOrd, PartialEq)] +#[derive(Clone, Hash, Ord, Eq, PartialOrd, PartialEq)] pub struct ImString(Vec); impl ImString { @@ -56,6 +56,18 @@ impl ImString { } } +impl<'a> Default for ImString { + fn default() -> ImString { unsafe { ImString::from_utf8_with_nul_unchecked(vec![0]) } } +} + +impl From for ImString { + fn from(s: String) -> ImString { ImString::new(s) } +} + +impl<'a, T: ?Sized + AsRef> From<&'a T> for ImString { + fn from(s: &'a T) -> ImString { s.as_ref().to_owned() } +} + impl AsRef for ImString { fn as_ref(&self) -> &ImStr { self } } @@ -64,11 +76,21 @@ impl Borrow for ImString { fn borrow(&self) -> &ImStr { self } } +impl AsRef for ImString { + fn as_ref(&self) -> &str { self.to_str() } +} + +impl Borrow for ImString { + fn borrow(&self) -> &str { self.to_str() } +} + +impl Index for ImString { + type Output = ImStr; + fn index(&self, _index: RangeFull) -> &ImStr { self } +} + impl fmt::Debug for ImString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let s: &str = self; - fmt::Debug::fmt(s, f) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(self.to_str(), f) } } impl Deref for ImString { @@ -80,11 +102,7 @@ impl Deref for ImString { } } -impl<'a> From<&'a ImStr> for ImString { - fn from(value: &'a ImStr) -> ImString { value.to_owned() } -} - -#[derive(Hash)] +#[derive(Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct ImStr(CStr); impl<'a> Default for &'a ImStr { @@ -99,15 +117,12 @@ impl fmt::Debug for ImStr { } impl ImStr { + pub fn new + ?Sized>(s: &S) -> &ImStr { s.as_ref() } pub unsafe fn from_utf8_with_nul_unchecked(bytes: &[u8]) -> &ImStr { mem::transmute(bytes) } pub fn as_ptr(&self) -> *const c_char { self.0.as_ptr() } pub fn to_str(&self) -> &str { unsafe { str::from_utf8_unchecked(self.0.to_bytes()) } } } -impl<'a> Into<&'a CStr> for &'a ImStr { - fn into(self) -> &'a CStr { &self.0 } -} - impl AsRef for ImStr { fn as_ref(&self) -> &CStr { &self.0 } } @@ -116,12 +131,11 @@ impl AsRef for ImStr { fn as_ref(&self) -> &ImStr { self } } +impl AsRef for ImStr { + fn as_ref(&self) -> &str { self.to_str() } +} + impl ToOwned for ImStr { type Owned = ImString; fn to_owned(&self) -> ImString { ImString(self.0.to_owned().into_bytes()) } } - -impl Deref for ImStr { - type Target = str; - fn deref(&self) -> &str { unsafe { str::from_utf8_unchecked(self.0.to_bytes()) } } -}