Skip to content

Commit

Permalink
Add IterateObject utility
Browse files Browse the repository at this point in the history
  • Loading branch information
zcbenz committed Jul 19, 2024
1 parent 8d67386 commit d3e1122
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 27 deletions.
28 changes: 26 additions & 2 deletions src/iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace ki {

template<typename T>
bool IterateArray(napi_env env, napi_value arr,
const std::function<void(uint32_t i, T value)>& visit) {
const std::function<bool(uint32_t i, T value)>& visit) {
if (!IsArray(env, arr))
return false;
uint32_t length;
Expand All @@ -20,11 +20,35 @@ bool IterateArray(napi_env env, napi_value arr,
std::optional<T> out = FromNodeTo<T>(env, el);
if (!out)
return false;
visit(i, *out);
if (!visit(i, *out))
return false;
}
return true;
}

template<typename K, typename V>
bool IterateObject(napi_env env, napi_value obj,
const std::function<bool(K key, V value)>& visit) {
if (!IsType(env, obj, napi_object))
return false;
napi_value property_names;
if (napi_get_property_names(env, obj, &property_names) != napi_ok)
return false;
auto visit_arr = [&env, &obj, &visit](uint32_t i, napi_value key) {
std::optional<K> k = FromNodeTo<K>(env, key);
if (!k)
return false;
napi_value value;
if (napi_get_property(env, obj, key, &value) != napi_ok)
return false;
std::optional<V> v = FromNodeTo<V>(env, value);
if (!v)
return false;
return visit(std::move(*k), std::move(*v));
};
return IterateArray<napi_value>(env, property_names, visit_arr);
}

} // namespace ki

#endif // SRC_ITERATOR_H_
43 changes: 18 additions & 25 deletions src/std_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,15 @@ struct Type<std::vector<T>> {
}
static std::optional<std::vector<T>> FromNode(napi_env env,
napi_value value) {
std::vector<T> r;
std::vector<T> result;
if (!IterateArray<T>(env, value,
[&](uint32_t i, T v) { r.push_back(std::move(v)); })) {
[&](uint32_t i, T value) {
result.push_back(std::move(value));
return true;
})) {
return std::nullopt;
}
return r;
return result;
}
};

Expand All @@ -110,12 +113,15 @@ struct Type<std::set<T>> {
}
static std::optional<std::set<T>> FromNode(napi_env env,
napi_value value) {
std::set<T> r;
std::set<T> result;
if (!IterateArray<T>(env, value,
[&](uint32_t i, T v) { r.insert(std::move(v)); })) {
[&](uint32_t i, T value) {
result.insert(std::move(value));
return true;
})) {
return std::nullopt;
}
return r;
return result;
}
};

Expand Down Expand Up @@ -147,26 +153,13 @@ struct Type<T, std::enable_if_t< // is map type
}
static std::optional<T> FromNode(napi_env env,
napi_value object) {
if (!IsType(env, object, napi_object))
return std::nullopt;
napi_value property_names;
if (napi_get_property_names(env, object, &property_names) != napi_ok)
return std::nullopt;
auto keys = FromNodeTo<std::vector<napi_value>>(env, property_names);
if (!keys)
return std::nullopt;
T result;
for (napi_value key : *keys) {
std::optional<K> k = FromNodeTo<K>(env, key);
if (!k)
return std::nullopt;
napi_value value;
if (napi_get_property(env, object, key, &value) != napi_ok)
return std::nullopt;
std::optional<V> v = FromNodeTo<V>(env, value);
if (!v)
return std::nullopt;
result.emplace(std::move(*k), std::move(*v));
if (!IterateObject<K, V>(env, object,
[&result](K key, V value) {
result.emplace(std::move(key), std::move(value));
return true;
})) {
return std::nullopt;
}
return result;
}
Expand Down

0 comments on commit d3e1122

Please sign in to comment.