diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bed01d..2e10d88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ nanosecond precision. - 'old-api' feature, which disables deprecation warnings for the old api is no longer a default feature. +- `RString::to_string` will now use a Ruby utf-8 validation api that caches the + results of the validity check. This will greatly improve performance in the + case a string is already known to be utf-8, but may slightly reduce + performance when not known. ### Deprecated diff --git a/src/r_string.rs b/src/r_string.rs index 51312cf..bfa2cd8 100644 --- a/src/r_string.rs +++ b/src/r_string.rs @@ -1165,14 +1165,13 @@ impl RString { /// ``` pub fn to_string(self) -> Result { let handle = Ruby::get_with(self); - let utf8 = if self.is_utf8_compatible_encoding() { - self - } else { - self.conv_enc(handle.utf8_encoding())? - }; - str::from_utf8(unsafe { utf8.as_slice() }) - .map(ToOwned::to_owned) - .map_err(|e| Error::new(handle.exception_encoding_error(), format!("{}", e))) + unsafe { + if let Some(str) = self.test_as_str() { + Ok(str.to_owned()) + } else { + Ok(self.conv_enc(handle.utf8_encoding())?.as_str()?.to_owned()) + } + } } /// Returns `self` as an owned Rust `Bytes`.