Skip to content

Commit

Permalink
feat: add LDValue_SerializeJSON C binding
Browse files Browse the repository at this point in the history
  • Loading branch information
cwaldren-ld committed Oct 17, 2024
1 parent d2a2b61 commit f9cdb11
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
7 changes: 6 additions & 1 deletion libs/common/include/launchdarkly/bindings/c/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,12 @@ LD_EXPORT(unsigned int)
LDValue_Count(LDValue val);

/**
* Serializes the LDValue to a JSON value.
* Serializes the LDValue to a JSON value. The returning string should be
* freed with @ref LDMemory_FreeString.
*
* Please note that numbers are serialized using scientific notation;
* for example the number 17 would be serialized as '1.7E1'.
*
* @param val Target LDValue. Must not be NULL.
* @return A string containing the JSON representation of the LDValue. The
* string should be freed with @ref LDMemory_FreeString.
Expand Down
55 changes: 55 additions & 0 deletions libs/common/tests/bindings/value_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "launchdarkly/bindings/c/object_builder.h"
#include "launchdarkly/bindings/c/value.h"

#include "launchdarkly/bindings/c/memory_routines.h"

TEST(ValueCBindingTests, CanCreateNull) {
auto* ptr = LDValue_NewNull();

Expand Down Expand Up @@ -168,3 +170,56 @@ TEST(ValueCBindingTests, CanCreateObject) {

LDValue_Free(val_ptr);
}

// Helper to serialize an LDValue, automatically converts to
// std::string and frees the result using LDMemory_FreeString.
std::string serialize(LDValue const val) {
char* serialized = LDValue_SerializeJSON(val);
std::string result(serialized);
LDMemory_FreeString(serialized);
return result;
}

TEST(ValueCBindingTests, CanSerializeToJSON) {
auto* null_val = LDValue_NewNull();
auto* bool_val_true = LDValue_NewBool(true);
auto* bool_val_false = LDValue_NewBool(false);

auto* num_val = LDValue_NewNumber(17);

Check warning on line 188 in libs/common/tests/bindings/value_test.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/libs/common/tests/bindings/value_test.cpp:188:39 [cppcoreguidelines-avoid-magic-numbers

17 is a magic number; consider replacing it with a named constant
auto* float_val = LDValue_NewNumber(3.141);

Check warning on line 189 in libs/common/tests/bindings/value_test.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

/libs/common/tests/bindings/value_test.cpp:189:41 [cppcoreguidelines-avoid-magic-numbers

3.141 is a magic number; consider replacing it with a named constant
auto* str_val = LDValue_NewString("Potato");

EXPECT_EQ("null", serialize(null_val));
EXPECT_EQ("true", serialize(bool_val_true));
EXPECT_EQ("false", serialize(bool_val_false));
EXPECT_EQ("1.7E1", serialize(num_val));
EXPECT_EQ("3.141E0", serialize(float_val));
EXPECT_EQ("\"Potato\"", serialize(str_val));

// Object builder is going to take care of freeing all the primitives
// (except for bool_val_false.)
auto* object_builder = LDObjectBuilder_New();
LDObjectBuilder_Add(object_builder, "null", null_val);
LDObjectBuilder_Add(object_builder, "bool", bool_val_true);
LDObjectBuilder_Add(object_builder, "num", num_val);
LDObjectBuilder_Add(object_builder, "float", float_val);
LDObjectBuilder_Add(object_builder, "str", str_val);

auto* obj_ptr = LDObjectBuilder_Build(object_builder);

EXPECT_EQ(
"{\"bool\":true,\"float\":3.141E0,\"null\":null,\"num\":1.7E1,\"str\":"
"\"Potato\"}",
serialize(obj_ptr));

LDValue_Free(obj_ptr);

// Array builder is going to take care of freeing bool_val_false.
auto* array_builder = LDArrayBuilder_New();
LDArrayBuilder_Add(array_builder, bool_val_false);
auto* array_ptr = LDArrayBuilder_Build(array_builder);

EXPECT_EQ("[false]", serialize(array_ptr));

LDValue_Free(array_ptr);
}

0 comments on commit f9cdb11

Please sign in to comment.