-
Notifications
You must be signed in to change notification settings - Fork 3
feat: Implement context filtering and JSON serialization. #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0969cfe
00a282f
88d1039
b850ba9
37ef70a
af2f0dd
e2f00ee
c1c42af
b936308
b68b96e
71cccf0
019731a
78e372b
ca340c0
375353d
472830f
d484bba
9687c87
9185e32
27ba8ef
2e079ca
331af8b
355b22e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| #pragma once | ||
|
|
||
| #include <string> | ||
| #include <unordered_set> | ||
| #include <vector> | ||
|
|
||
| #include <boost/json.hpp> | ||
|
|
||
| #include "attribute_reference.hpp" | ||
| #include "context.hpp" | ||
|
|
||
| namespace launchdarkly { | ||
|
|
||
| /** | ||
| * Class used by the SDK for filtering contexts to produce redacted JSON | ||
| * for analytics events. | ||
| */ | ||
| class ContextFilter { | ||
| public: | ||
| using JsonValue = boost::json::value; | ||
| using JsonObject = boost::json::object; | ||
| using JsonArray = boost::json::array; | ||
|
|
||
| ContextFilter(bool all_attributes_private, | ||
| AttributeReference::SetType const& global_private_attributes); | ||
|
|
||
| /** | ||
| * Filter the given context and produce a JSON value. | ||
| * | ||
| * Only call this method for valid contexts. | ||
| * | ||
| * @param context The context to redact. | ||
| * @return JSON suitable for an analytics event. | ||
| */ | ||
| JsonValue filter(Context const& context); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wonder if it'd be highly inconvenient to guarantee that all Contexts are valid.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In what sense? It should be easy to always be valid before this call, because we don't put invalid contexts into events, and many events we don't send at all if the context was not valid.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In regards to all contexts being valid, I think that would preclude the ability to dynamically populate contexts. |
||
|
|
||
| private: | ||
| /** | ||
| * The filtering and JSON conversion algorithm is stack based | ||
| * instead of recursive. Each node is visited, and if that node is a basic | ||
| * type bool, number, string, then it is processed immediately, being | ||
| * added to the output object. If the node is complex, then each of its | ||
| * immediately children is added to the stack to be processed. | ||
| */ | ||
| struct StackItem { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I generally try to avoid recursive implementations outside functional languages. I have done that here, but I have not specifically benchmarked and compared the stack size and performance between the two implementations. |
||
| Value const& value; | ||
| std::vector<std::string_view> path; | ||
| JsonValue& parent; | ||
| }; | ||
|
|
||
| /** | ||
| * Put an item into its parent. Either as a pair in a map, | ||
| * or pushed onto an array. | ||
| * @param item The stack item denoting placement information. | ||
| * @param addition The item to add. | ||
| */ | ||
| static void emplace(StackItem& item, JsonValue&& addition); | ||
|
|
||
| /** | ||
| * If the path needs to be redacted, then redact it and add it to the redactions. | ||
| * @param redactions The list of redacted items. | ||
| * @param path The path to check. | ||
| * @param attributes Attributes which may contain additional private | ||
| * attributes. | ||
| * @return True if the item was redacted. | ||
| */ | ||
| bool redact(std::vector<std::string>& redactions, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is redact being called multiple times to build up the redactions list? or is this a candidate for a return value (once the tl::expected is in)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same list is used throughout the process. |
||
| std::vector<std::string_view> path, | ||
| Attributes const& attributes); | ||
|
|
||
| /** | ||
| * Append a container to the parent. | ||
| * @param item The stack item containing the parent. | ||
| * @param value The container to append. | ||
| * @return The appended container. | ||
| */ | ||
| static JsonValue* append_container(StackItem& item, JsonValue&& value); | ||
|
|
||
| /** | ||
| * Put a simple value into the parent specified by its stack item. | ||
| * @param item The stack item with value information and the parent. | ||
| */ | ||
| static void append_simple_type(StackItem& item); | ||
|
|
||
| JsonValue filter_single_context(std::string_view kind, | ||
| bool include_kind, | ||
| Attributes const& attributes); | ||
|
|
||
| JsonValue filter_multi_context(Context const& context); | ||
|
|
||
| bool all_attributes_private_; | ||
| AttributeReference::SetType const& global_private_attributes_; | ||
| }; | ||
|
|
||
| } // namespace launchdarkly | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,7 +53,7 @@ class Value { | |
| class Array { | ||
| public: | ||
| struct Iterator { | ||
| using iterator_category = std::forward_iterator_tag; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we can iterate the array either direction. |
||
| using iterator_category = std::bidirectional_iterator_tag; | ||
| using difference_type = std::ptrdiff_t; | ||
| using value_type = Value; | ||
| using pointer = value_type const*; | ||
|
|
@@ -66,6 +66,9 @@ class Value { | |
| Iterator& operator++(); | ||
| Iterator operator++(int); | ||
|
|
||
| Iterator& operator--(); | ||
| Iterator operator--(int); | ||
|
|
||
| friend bool operator==(Iterator const& lhs, Iterator const& rhs) { | ||
| return lhs.iterator_ == rhs.iterator_; | ||
| }; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.