Fix naming according to the Rust styleguide. am: 192e0bbc0f
Original change: https://android-review.googlesource.com/c/platform/system/tools/sysprop/+/2743333
Change-Id: Iefb05e2492eafe781684d18306896fd789c48296
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Common.cpp b/Common.cpp
index ec7d120..fc64099 100644
--- a/Common.cpp
+++ b/Common.cpp
@@ -360,3 +360,34 @@
return (isdigit(name[0]) ? "_" : "") +
std::regex_replace(name, kRegexAllowed, "_");
}
+
+std::string SnakeCaseToCamelCase(const std::string& s) {
+ std::string result;
+ for (int i = 0; i < s.size(); ++i) {
+ if (s[i] == '_') continue;
+ char current = tolower(s[i]); // Handle screaming snake case.
+ if (i == 0 || s[i - 1] == '_') {
+ current = toupper(current);
+ }
+ result += current;
+ }
+ return result;
+}
+
+std::string CamelCaseToSnakeCase(const std::string& s) {
+ // Desired behaviour: "CurrentAPIVersion" -> "current_api_version".
+ std::string result;
+ for (int i = 0; i < s.size(); ++i) {
+ char current = s[i];
+ char prev = (i > 0) ? s[i - 1] : 0;
+ char next = (i < s.size() - 1) ? s[i + 1] : 0;
+ if (prev && isupper(prev) && (!next || isupper(next) || !isalpha(next))) {
+ current = tolower(current);
+ }
+ if (i > 0 && isupper(current) && result[result.size() - 1] != '_') {
+ result += '_';
+ }
+ result += tolower(current);
+ }
+ return result;
+}
\ No newline at end of file
diff --git a/RustGen.cpp b/RustGen.cpp
index 5982f65..4390db5 100644
--- a/RustGen.cpp
+++ b/RustGen.cpp
@@ -192,12 +192,7 @@
std::string GetRustEnumType(const sysprop::Property& prop) {
std::string result = ApiNameToIdentifier(prop.api_name());
- for (int i = 0; i < result.size(); ++i) {
- if (i == 0 || result[i - 1] == '_') {
- result[i] = toupper(result[i]);
- }
- }
- return std::regex_replace(result, std::regex{"_"}, "") + "Values";
+ return SnakeCaseToCamelCase(result) + "Values";
}
std::string GetRustReturnType(const sysprop::Property& prop) {
@@ -313,14 +308,13 @@
}
return "gen_parsers_and_formatters::format_bool";
case sysprop::String:
- return "gen_parsers_and_formatters::format";
case sysprop::Integer:
case sysprop::UInt:
case sysprop::Long:
case sysprop::ULong:
case sysprop::Double:
case sysprop::Enum:
- return "gen_parsers_and_formatters::format_value";
+ return "gen_parsers_and_formatters::format";
case sysprop::BooleanList:
if (prop.integer_as_bool()) {
return "gen_parsers_and_formatters::format_bool_list_as_int";
@@ -351,7 +345,8 @@
const sysprop::Property& prop = props.prop(i);
if (prop.scope() > scope) continue;
- std::string prop_id = ApiNameToIdentifier(prop.api_name());
+ std::string prop_id =
+ CamelCaseToSnakeCase(ApiNameToIdentifier(prop.api_name()));
// Create enum.
if (prop.type() == sysprop::Enum || prop.type() == sysprop::EnumList) {
@@ -364,13 +359,13 @@
writer.Write("pub enum %s {\n", enum_type.c_str());
writer.Indent();
for (const std::string& value : values) {
- writer.Write("%s,\n", ToUpper(value).c_str());
+ writer.Write("%s,\n", SnakeCaseToCamelCase(value).c_str());
}
writer.Dedent();
writer.Write("}\n\n");
// Enum parser.
- writer.Write("impl FromStr for %s {\n", enum_type.c_str());
+ writer.Write("impl std::str::FromStr for %s {\n", enum_type.c_str());
writer.Indent();
writer.Write("type Err = String;\n\n");
writer.Write("fn from_str(s: &str) -> Result<Self, Self::Err> {\n");
@@ -379,7 +374,7 @@
writer.Indent();
for (const std::string& value : values) {
writer.Write("\"%s\" => Ok(%s::%s),\n", value.c_str(),
- enum_type.c_str(), ToUpper(value).c_str());
+ enum_type.c_str(), SnakeCaseToCamelCase(value).c_str());
}
writer.Write("_ => Err(format!(\"'{}' cannot be parsed for %s\", s)),\n",
enum_type.c_str());
@@ -400,7 +395,7 @@
writer.Indent();
for (const std::string& value : values) {
writer.Write("%s::%s => write!(f, \"%s\"),\n", enum_type.c_str(),
- ToUpper(value).c_str(), value.c_str());
+ SnakeCaseToCamelCase(value).c_str(), value.c_str());
}
writer.Write("_ => Err(fmt::Error),\n");
writer.Dedent();
diff --git a/include/Common.h b/include/Common.h
index 8ad6fb1..7d3a2ad 100644
--- a/include/Common.h
+++ b/include/Common.h
@@ -32,3 +32,5 @@
android::base::Result<sysprop::SyspropLibraryApis> ParseApiFile(
const std::string& file_path);
std::string ToUpper(std::string str);
+std::string CamelCaseToSnakeCase(const std::string& str);
+std::string SnakeCaseToCamelCase(const std::string& str);
diff --git a/tests/CommonTest.cpp b/tests/CommonTest.cpp
new file mode 100644
index 0000000..cd343f7
--- /dev/null
+++ b/tests/CommonTest.cpp
@@ -0,0 +1,39 @@
+/* Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/test_utils.h>
+#include <gtest/gtest.h>
+
+#include "Common.h"
+
+TEST(SyspropTest, CamelToSnakeTest) {
+ EXPECT_EQ(CamelCaseToSnakeCase("CurrentAPIVersion"), "current_api_version");
+ EXPECT_EQ(CamelCaseToSnakeCase("CurrentAPI"), "current_api");
+ EXPECT_EQ(CamelCaseToSnakeCase("APIVersion"), "api_version");
+ EXPECT_EQ(CamelCaseToSnakeCase("API"), "api");
+ EXPECT_EQ(CamelCaseToSnakeCase("API2"), "api2");
+ EXPECT_EQ(CamelCaseToSnakeCase("SomeRandomCamelCase"),
+ "some_random_camel_case");
+ EXPECT_EQ(CamelCaseToSnakeCase("snake_case"), "snake_case");
+ EXPECT_EQ(CamelCaseToSnakeCase("Strange_Camel_Case"), "strange_camel_case");
+}
+
+TEST(SyspropTest, SnakeToCamelTest) {
+ EXPECT_EQ(SnakeCaseToCamelCase("current_api_version"), "CurrentApiVersion");
+ EXPECT_EQ(SnakeCaseToCamelCase("random"), "Random");
+ EXPECT_EQ(SnakeCaseToCamelCase("SCREAMING_SNAKE_CASE_100"),
+ "ScreamingSnakeCase100");
+ EXPECT_EQ(SnakeCaseToCamelCase("double__underscore"), "DoubleUnderscore");
+}
\ No newline at end of file
diff --git a/tests/RustGenTest.cpp b/tests/RustGenTest.cpp
index e840005..ce58c0b 100644
--- a/tests/RustGenTest.cpp
+++ b/tests/RustGenTest.cpp
@@ -150,7 +150,7 @@
/// Sets the value of the property 'android.test_int', returns 'Ok' if successful.
pub fn set_test_int(v: i32) -> Result<()> {
- let value = gen_parsers_and_formatters::format_value(&v);
+ let value = gen_parsers_and_formatters::format(&v);
system_properties::write("android.test_int", value.as_str()).map_err(SysPropError::SetError)
}
@@ -171,7 +171,7 @@
}
/// Returns the value of the property 'ro.android.test.b' if set.
-pub fn test_BOOLeaN() -> Result<Option<bool>> {
+pub fn test_boo_lea_n() -> Result<Option<bool>> {
let result = match system_properties::read("ro.android.test.b") {
Err(e) => Err(SysPropError::FetchError(e)),
Ok(Some(val)) => gen_parsers_and_formatters::parse_bool(val.as_str()).map_err(SysPropError::ParseError).map(Some),
@@ -181,7 +181,7 @@
}
/// Sets the value of the property 'ro.android.test.b', returns 'Ok' if successful.
-pub fn set_test_BOOLeaN(v: bool) -> Result<()> {
+pub fn set_test_boo_lea_n(v: bool) -> Result<()> {
let value = gen_parsers_and_formatters::format_bool(&v);
system_properties::write("ro.android.test.b", value.as_str()).map_err(SysPropError::SetError)
}
@@ -198,7 +198,7 @@
/// Sets the value of the property 'android_os_test-long', returns 'Ok' if successful.
pub fn set_android_os_test_long(v: i64) -> Result<()> {
- let value = gen_parsers_and_formatters::format_value(&v);
+ let value = gen_parsers_and_formatters::format(&v);
system_properties::write("android_os_test-long", value.as_str()).map_err(SysPropError::SetError)
}
@@ -290,7 +290,7 @@
/// Sets the value of the property 'android.test_double', returns 'Ok' if successful.
pub fn set_test_double(v: f64) -> Result<()> {
- let value = gen_parsers_and_formatters::format_value(&v);
+ let value = gen_parsers_and_formatters::format(&v);
system_properties::write("android.test_double", value.as_str()).map_err(SysPropError::SetError)
}
@@ -306,7 +306,7 @@
/// Sets the value of the property 'android.test_int', returns 'Ok' if successful.
pub fn set_test_int(v: i32) -> Result<()> {
- let value = gen_parsers_and_formatters::format_value(&v);
+ let value = gen_parsers_and_formatters::format(&v);
system_properties::write("android.test_int", value.as_str()).map_err(SysPropError::SetError)
}
@@ -337,7 +337,7 @@
G,
}
-impl FromStr for TestEnumValues {
+impl std::str::FromStr for TestEnumValues {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
@@ -381,12 +381,12 @@
/// Sets the value of the property 'android.test.enum', returns 'Ok' if successful.
pub fn set_test_enum(v: TestEnumValues) -> Result<()> {
- let value = gen_parsers_and_formatters::format_value(&v);
+ let value = gen_parsers_and_formatters::format(&v);
system_properties::write("android.test.enum", value.as_str()).map_err(SysPropError::SetError)
}
/// Returns the value of the property 'ro.android.test.b' if set.
-pub fn test_BOOLeaN() -> Result<Option<bool>> {
+pub fn test_boo_lea_n() -> Result<Option<bool>> {
let result = match system_properties::read("ro.android.test.b") {
Err(e) => Err(SysPropError::FetchError(e)),
Ok(Some(val)) => gen_parsers_and_formatters::parse_bool(val.as_str()).map_err(SysPropError::ParseError).map(Some),
@@ -396,7 +396,7 @@
}
/// Sets the value of the property 'ro.android.test.b', returns 'Ok' if successful.
-pub fn set_test_BOOLeaN(v: bool) -> Result<()> {
+pub fn set_test_boo_lea_n(v: bool) -> Result<()> {
let value = gen_parsers_and_formatters::format_bool(&v);
system_properties::write("ro.android.test.b", value.as_str()).map_err(SysPropError::SetError)
}
@@ -413,7 +413,7 @@
/// Sets the value of the property 'android_os_test-long', returns 'Ok' if successful.
pub fn set_android_os_test_long(v: i64) -> Result<()> {
- let value = gen_parsers_and_formatters::format_value(&v);
+ let value = gen_parsers_and_formatters::format(&v);
system_properties::write("android_os_test-long", value.as_str()).map_err(SysPropError::SetError)
}
@@ -469,19 +469,19 @@
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Hash, Ord)]
pub enum ElValues {
- ENU,
- MVA,
- LUE,
+ Enu,
+ Mva,
+ Lue,
}
-impl FromStr for ElValues {
+impl std::str::FromStr for ElValues {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
- "enu" => Ok(ElValues::ENU),
- "mva" => Ok(ElValues::MVA),
- "lue" => Ok(ElValues::LUE),
+ "enu" => Ok(ElValues::Enu),
+ "mva" => Ok(ElValues::Mva),
+ "lue" => Ok(ElValues::Lue),
_ => Err(format!("'{}' cannot be parsed for ElValues", s)),
}
}
@@ -490,9 +490,9 @@
impl fmt::Display for ElValues {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
- ElValues::ENU => write!(f, "enu"),
- ElValues::MVA => write!(f, "mva"),
- ElValues::LUE => write!(f, "lue"),
+ ElValues::Enu => write!(f, "enu"),
+ ElValues::Mva => write!(f, "mva"),
+ ElValues::Lue => write!(f, "lue"),
_ => Err(fmt::Error),
}
}