feat: add String::New overload for string_view (#1706)
* Add String::New overload for string_view
* Add Symbol::New with string_view
* Add String/Symbol::New with string view unit tests
* Add doc for String and Symbol string_view constructors
diff --git a/doc/string.md b/doc/string.md
index bb04f66..7a94a4d 100644
--- a/doc/string.md
+++ b/doc/string.md
@@ -60,6 +60,7 @@
Napi::String::New(napi_env env, const char16_t* value);
Napi::String::New(napi_env env, const char* value, size_t length);
Napi::String::New(napi_env env, const char16_t* value, size_t length);
+Napi::String::New(napi_env env, std::string_view value);
```
- `[in] env`: The `napi_env` environment in which to construct the `Napi::Value` object.
@@ -68,6 +69,7 @@
- `std::u16string&` - represents a UTF16-LE string.
- `const char*` - represents a UTF8 string.
- `const char16_t*` - represents a UTF16-LE string.
+ - `std::string_view` - represents a UTF8 string view.
- `[in] length`: The length of the string (not necessarily null-terminated) in code units.
Returns a new `Napi::String` that represents the passed in C++ string.
diff --git a/doc/symbol.md b/doc/symbol.md
index e233267..d94a618 100644
--- a/doc/symbol.md
+++ b/doc/symbol.md
@@ -18,6 +18,7 @@
```cpp
Napi::Symbol::New(napi_env env, const std::string& description);
Napi::Symbol::New(napi_env env, const char* description);
+Napi::Symbol::New(napi_env env, std::string_view description);
Napi::Symbol::New(napi_env env, Napi::String description);
Napi::Symbol::New(napi_env env, napi_value description);
```
@@ -27,6 +28,7 @@
`description` may be any of:
- `std::string&` - UTF8 string description.
- `const char*` - represents a UTF8 string description.
+ - `std::string_view` - represents a UTF8 string view.
- `String` - Node addon API String description.
- `napi_value` - Node-API `napi_value` description.
@@ -58,4 +60,4 @@
Searches in the global registry for existing symbol with the given name. If the symbol already exist it will be returned, otherwise a new symbol will be created in the registry. It's equivalent to Symbol.for() called from JavaScript.
-[`Napi::Name`]: ./name.md
\ No newline at end of file
+[`Napi::Name`]: ./name.md
diff --git a/napi-inl.h b/napi-inl.h
index 568a6ba..7824562 100644
--- a/napi-inl.h
+++ b/napi-inl.h
@@ -18,6 +18,7 @@
#if NAPI_HAS_THREADS
#include <mutex>
#endif // NAPI_HAS_THREADS
+#include <string_view>
#include <type_traits>
#include <utility>
@@ -1262,6 +1263,10 @@
return String::New(env, val.c_str(), val.size());
}
+inline String String::New(napi_env env, std::string_view val) {
+ return String::New(env, val.data(), val.size());
+}
+
inline String String::New(napi_env env, const char* val) {
// TODO(@gabrielschulhof) Remove if-statement when core's error handling is
// available in all supported versions.
@@ -1371,6 +1376,11 @@
return Symbol::New(env, descriptionValue);
}
+inline Symbol Symbol::New(napi_env env, std::string_view description) {
+ napi_value descriptionValue = String::New(env, description);
+ return Symbol::New(env, descriptionValue);
+}
+
inline Symbol Symbol::New(napi_env env, String description) {
napi_value descriptionValue = description;
return Symbol::New(env, descriptionValue);
diff --git a/napi.h b/napi.h
index 4efe551..ba5c557 100644
--- a/napi.h
+++ b/napi.h
@@ -19,6 +19,7 @@
#endif // NAPI_HAS_THREADS
#include <chrono>
#include <string>
+#include <string_view>
#include <vector>
// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known
@@ -725,6 +726,11 @@
const std::u16string& value ///< UTF-16 encoded C++ string
);
+ /// Creates a new String value from a UTF-8 encoded C++ string view.
+ static String New(napi_env env, ///< Node-API environment
+ std::string_view value ///< UTF-8 encoded C++ string view
+ );
+
/// Creates a new String value from a UTF-8 encoded C string.
static String New(
napi_env env, ///< Node-API environment
@@ -799,6 +805,13 @@
);
/// Creates a new Symbol value with a description.
+ static Symbol New(
+ napi_env env, ///< Node-API environment
+ std::string_view
+ description ///< UTF-8 encoded C++ string view describing the symbol
+ );
+
+ /// Creates a new Symbol value with a description.
static Symbol New(napi_env env, ///< Node-API environment
String description ///< String value describing the symbol
);
diff --git a/test/name.cc b/test/name.cc
index 27bab93..d94a393 100644
--- a/test/name.cc
+++ b/test/name.cc
@@ -1,5 +1,7 @@
#include "napi.h"
+#include <string_view>
+
using namespace Napi;
const char* testValueUtf8 = "123456789";
@@ -43,6 +45,10 @@
}
}
+Value CreateStringFromStringView(const CallbackInfo& info) {
+ return String::New(info.Env(), std::string_view("hello1"));
+}
+
Value CheckString(const CallbackInfo& info) {
String value = info[0].As<String>();
String encoding = info[1].As<String>();
@@ -80,6 +86,10 @@
}
}
+Value CreateSymbolFromStringView(const CallbackInfo& info) {
+ return Symbol::New(info.Env(), std::string_view("hello2"));
+}
+
Value CheckSymbol(const CallbackInfo& info) {
return Boolean::New(info.Env(), info[0].Type() == napi_symbol);
}
@@ -99,11 +109,15 @@
exports["echoString"] = Function::New(env, EchoString);
exports["createString"] = Function::New(env, CreateString);
+ exports["createStringFromStringView"] =
+ Function::New(env, CreateStringFromStringView);
exports["nullStringShouldThrow"] = Function::New(env, NullStringShouldThrow);
exports["nullString16ShouldThrow"] =
Function::New(env, NullString16ShouldThrow);
exports["checkString"] = Function::New(env, CheckString);
exports["createSymbol"] = Function::New(env, CreateSymbol);
+ exports["createSymbolFromStringView"] =
+ Function::New(env, CreateSymbolFromStringView);
exports["checkSymbol"] = Function::New(env, CheckSymbol);
return exports;
diff --git a/test/name.js b/test/name.js
index 406c533..8113565 100644
--- a/test/name.js
+++ b/test/name.js
@@ -56,4 +56,9 @@
assert.strictEqual(binding.name.echoString(str, 'utf8'), str);
assert.strictEqual(binding.name.echoString(str, 'utf16'), str);
}
+
+ assert.strictEqual(binding.name.createStringFromStringView(), 'hello1');
+ const symFromStringView = binding.name.createSymbolFromStringView();
+ assert.strictEqual(typeof symFromStringView, 'symbol');
+ assert.strictEqual(symFromStringView.description, 'hello2');
}