From 932319256f88419fc67c10cc6612b920b6018fe2 Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Wed, 12 Jul 2017 23:30:27 +0300 Subject: [PATCH] Restructure ImString/ImStr creation functions --- CHANGELOG.markdown | 11 +++++++++++ src/lib.rs | 6 ++---- src/sliders.rs | 8 ++++---- src/string.rs | 24 ++++++++++++++++++------ 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 7b2e1be..687a5ce 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -9,10 +9,21 @@ - Support for scoped style customization - Support for scoped color customization - Support for child frames +- Unsafe ImString/ImStr creation functions for advanced users: + + `ImString::from_utf8_unchecked` (renamed from `ImString::from_bytes_unchecked`) + + `ImString::from_utf8_with_nul_unchecked`) + + `ImStr::from_utf8_with_nul_unchecked` (renamed from `ImStr::from_bytes_unchecked`) ### Changed - Button, selectable, and progress bar accept size with `Into` +- `ImString::new` always succeeds and any interior NULs truncate the string. **Breaking change** + +### Deprecated + +- `ImString::from_string_unchecked` (please use `ImString::new`) +- `ImString::from_bytes_unchecked` (renamed to `ImString::from_utf8_unchecked`) +- `ImStr::from_bytes_unchecked` (renamed to `ImStr::from_utf8_with_nul_unchecked`) ## [0.0.14] - 2017-06-18 diff --git a/src/lib.rs b/src/lib.rs index e0b434a..0d6e7c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,15 +71,13 @@ pub struct ImGui { #[macro_export] macro_rules! im_str { ($e:tt) => ({ - debug_assert!(!($e).as_bytes().contains(&0)); let value = concat!($e, "\0"); - unsafe { ::imgui::ImStr::from_bytes_unchecked(value.as_bytes()) } + unsafe { ::imgui::ImStr::from_utf8_with_nul_unchecked(value.as_bytes()) } }); ($e:tt, $($arg:tt)*) => ({ let mut bytes: Vec = format!($e, $($arg)*).into(); - debug_assert!(!bytes.contains(&0)); bytes.push(b'\0'); - unsafe { &::imgui::ImString::from_vec_unchecked(bytes) } + unsafe { &::imgui::ImString::from_utf8_unchecked(bytes) } }) } diff --git a/src/sliders.rs b/src/sliders.rs index b7da3ee..a68aee2 100644 --- a/src/sliders.rs +++ b/src/sliders.rs @@ -22,7 +22,7 @@ impl<'ui, 'p> SliderInt<'ui, 'p> { value: value, min: min, max: max, - display_format: unsafe { ImStr::from_bytes_unchecked(b"%.0f\0") }, + display_format: unsafe { ImStr::from_utf8_with_nul_unchecked(b"%.0f\0") }, _phantom: PhantomData, } } @@ -61,7 +61,7 @@ macro_rules! impl_slider_intn { value: value, min: min, max: max, - display_format: unsafe { ImStr::from_bytes_unchecked(b"%.0f\0") }, + display_format: unsafe { ImStr::from_utf8_with_nul_unchecked(b"%.0f\0") }, _phantom: PhantomData, } } @@ -106,7 +106,7 @@ impl<'ui, 'p> SliderFloat<'ui, 'p> { value: value, min: min, max: max, - display_format: unsafe { ImStr::from_bytes_unchecked(b"%.3f\0") }, + display_format: unsafe { ImStr::from_utf8_with_nul_unchecked(b"%.3f\0") }, power: 1.0, _phantom: PhantomData, } @@ -153,7 +153,7 @@ macro_rules! impl_slider_floatn { value: value, min: min, max: max, - display_format: unsafe { ImStr::from_bytes_unchecked(b"%.3f\0") }, + display_format: unsafe { ImStr::from_utf8_with_nul_unchecked(b"%.3f\0") }, power: 1.0, _phantom: PhantomData, } diff --git a/src/string.rs b/src/string.rs index f713eea..e079cc5 100644 --- a/src/string.rs +++ b/src/string.rs @@ -1,5 +1,5 @@ use std::borrow::Borrow; -use std::ffi::{CStr, CString, NulError}; +use std::ffi::{CStr}; use std::fmt; use std::mem; use std::ops::Deref; @@ -10,21 +10,29 @@ use std::str; pub struct ImString(Vec); impl ImString { - pub fn new>(t: T) -> Result { - CString::new(t.into()).map(|cstring| ImString(cstring.into_bytes_with_nul())) + pub fn new>(value: T) -> ImString { + unsafe { ImString::from_utf8_unchecked(value.into().into_bytes()) } } pub fn with_capacity(capacity: usize) -> ImString { let mut v = Vec::with_capacity(capacity + 1); v.push(b'\0'); ImString(v) } + #[deprecated(since = "0.0.15", note = "please use ImString::new instead")] pub unsafe fn from_string_unchecked(s: String) -> ImString { - ImString::from_vec_unchecked(s.into()) + ImString::new(s) } - pub unsafe fn from_vec_unchecked(mut v: Vec) -> ImString { + #[deprecated(since = "0.0.15", note = "please use ImString::from_utf8_unchecked instead")] + pub unsafe fn from_vec_unchecked(v: Vec) -> ImString { + ImString::from_utf8_unchecked(v) + } + pub unsafe fn from_utf8_unchecked(mut v: Vec) -> ImString { v.push(b'\0'); ImString(v) } + pub unsafe fn from_utf8_with_nul_unchecked(v: Vec) -> ImString { + ImString(v) + } pub fn clear(&mut self) { self.0.clear(); self.0.push(b'\0'); @@ -96,7 +104,7 @@ pub struct ImStr(CStr); impl<'a> Default for &'a ImStr { fn default() -> &'a ImStr { static SLICE: &'static [u8] = &[0]; - unsafe { ImStr::from_bytes_unchecked(SLICE) } + unsafe { ImStr::from_utf8_with_nul_unchecked(SLICE) } } } @@ -107,7 +115,11 @@ impl fmt::Debug for ImStr { } impl ImStr { + #[deprecated(since = "0.0.15", note = "please use ImStr::from_bytes_with_nul_unchecked instead")] pub unsafe fn from_bytes_unchecked<'a>(bytes: &'a [u8]) -> &'a ImStr { + ImStr::from_utf8_with_nul_unchecked(bytes) + } + pub unsafe fn from_utf8_with_nul_unchecked<'a>(bytes: &'a [u8]) -> &'a ImStr { mem::transmute(bytes) } pub fn as_ptr(&self) -> *const c_char { self.0.as_ptr() }