aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/protobuf/json/util.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/protobuf/json/util.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/protobuf/json/util.cpp')
-rw-r--r--library/cpp/protobuf/json/util.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/library/cpp/protobuf/json/util.cpp b/library/cpp/protobuf/json/util.cpp
new file mode 100644
index 0000000000..53a065eee2
--- /dev/null
+++ b/library/cpp/protobuf/json/util.cpp
@@ -0,0 +1,76 @@
+#include "util.h"
+
+#include <util/string/ascii.h>
+
+namespace {
+ void ToSnakeCaseImpl(TString* const name, std::function<bool(const char)> requiresUnderscore) {
+ bool requiresChanges = false;
+ size_t size = name->size();
+ for (size_t i = 0; i < name->size(); i++) {
+ if (IsAsciiUpper(name->at(i))) {
+ requiresChanges = true;
+ if (i > 0 && requiresUnderscore(name->at(i - 1))) {
+ size++;
+ }
+ }
+ }
+
+ if (!requiresChanges) {
+ return;
+ }
+
+ if (size != name->size()) {
+ TString result;
+ result.reserve(size);
+ for (size_t i = 0; i < name->size(); i++) {
+ const char c = name->at(i);
+ if (IsAsciiUpper(c)) {
+ if (i > 0 && requiresUnderscore(name->at(i - 1))) {
+ result += '_';
+ }
+ result += AsciiToLower(c);
+ } else {
+ result += c;
+ }
+ }
+ *name = std::move(result);
+ } else {
+ name->to_lower();
+ }
+ }
+}
+
+namespace NProtobufJson {
+ void ToSnakeCase(TString* const name) {
+ ToSnakeCaseImpl(name, [](const char prev) { return prev != '_'; });
+ }
+
+ void ToSnakeCaseDense(TString* const name) {
+ ToSnakeCaseImpl(name, [](const char prev) { return prev != '_' && !IsAsciiUpper(prev); });
+ }
+
+ bool EqualsIgnoringCaseAndUnderscores(TStringBuf s1, TStringBuf s2) {
+ size_t i1 = 0, i2 = 0;
+
+ while (i1 < s1.size() && i2 < s2.size()) {
+ if (s1[i1] == '_') {
+ ++i1;
+ } else if (s2[i2] == '_') {
+ ++i2;
+ } else if (AsciiToUpper(s1[i1]) != AsciiToUpper(s2[i2])) {
+ return false;
+ } else {
+ ++i1, ++i2;
+ }
+ }
+
+ while (i1 < s1.size() && s1[i1] == '_') {
+ ++i1;
+ }
+ while (i2 < s2.size() && s2[i2] == '_') {
+ ++i2;
+ }
+
+ return (i1 == s1.size() && i2 == s2.size());
+ }
+}