From ab3a08613231cc51dfb68e0eef14e83200459c8a Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 22 Jan 2020 17:23:42 +0100 Subject: [PATCH] Add String::new_empty() (#238) --- src/binding.cc | 4 ++++ src/string.rs | 12 ++++++++++++ tests/test_api.rs | 17 +++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/binding.cc b/src/binding.cc index 75386810..992a058f 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -612,6 +612,10 @@ long std__shared_ptr__v8__BackingStore__use_count( return ptr.use_count(); } +v8::String* v8__String__Empty(v8::Isolate* isolate) { + return local_to_ptr(v8::String::Empty(isolate)); +} + v8::String* v8__String__NewFromUtf8(v8::Isolate* isolate, const char* data, v8::NewStringType type, int length) { return maybe_local_to_ptr( diff --git a/src/string.rs b/src/string.rs index 77a11fef..811d3432 100644 --- a/src/string.rs +++ b/src/string.rs @@ -12,6 +12,8 @@ use crate::String; use crate::ToLocal; extern "C" { + fn v8__String__Empty(isolate: *mut Isolate) -> *mut String; + fn v8__String__NewFromUtf8( isolate: *mut Isolate, data: *const char, @@ -61,11 +63,21 @@ bitflags! { } impl String { + pub fn new_empty<'sc>(scope: &mut impl ToLocal<'sc>) -> Local<'sc, String> { + let ptr = unsafe { v8__String__Empty(scope.isolate()) }; + // FIXME(bnoordhuis) v8__String__Empty() is infallible so there + // is no need to box up the result, only to unwrap it again. + unsafe { scope.to_local(ptr) }.unwrap() + } + pub fn new_from_utf8<'sc>( scope: &mut impl ToLocal<'sc>, buffer: &[u8], new_type: NewStringType, ) -> Option> { + if buffer.is_empty() { + return Some(Self::new_empty(scope)); + } let ptr = unsafe { v8__String__NewFromUtf8( scope.isolate(), diff --git a/tests/test_api.rs b/tests/test_api.rs index 81512e70..c2adf2f4 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -149,6 +149,23 @@ fn test_string() { assert_eq!(17, local.utf8_length(scope)); assert_eq!(reference, local.to_rust_string_lossy(scope)); } + { + let mut hs = v8::HandleScope::new(scope); + let scope = hs.enter(); + let local = v8::String::new_empty(scope); + assert_eq!(0, local.length()); + assert_eq!(0, local.utf8_length(scope)); + assert_eq!("", local.to_rust_string_lossy(scope)); + } + { + let mut hs = v8::HandleScope::new(scope); + let scope = hs.enter(); + let local = + v8::String::new_from_utf8(scope, b"", v8::NewStringType::Normal).unwrap(); + assert_eq!(0, local.length()); + assert_eq!(0, local.utf8_length(scope)); + assert_eq!("", local.to_rust_string_lossy(scope)); + } } #[test]