Skip to content

Commit

Permalink
[Rust] Enhance enum supporting fromstr and display and into (#1020)
Browse files Browse the repository at this point in the history
* [Rust] impl FromStr for generated enum items

* [Rust] impl Display for generate enum items

* [Rust] impl Into for generated enum items

* [Rust] reformat code according to checkstyle failure report

* [Rust] split code in generateEnum to adress CI checkstyle method too log failure

* [Rust] reformat code according to checkstyle failure

* [Rust] fix CodeQL warning by removing unused argument

* [Rust] fix CodeQL warning by removing unused argument
  • Loading branch information
wbprime authored Nov 13, 2024
1 parent 4484457 commit 320850d
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
21 changes: 21 additions & 0 deletions rust/tests/baseline_enum_from_str.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use examples_baseline::{
boost_type::BoostType,
};

#[test]
fn test_boost_type_from_str() -> Result<(), ()> {
assert_eq!("TURBO".parse::<BoostType>()?, BoostType::TURBO, "Parse \"TURBO\" as BoostType");
assert_eq!("SUPERCHARGER".parse::<BoostType>()?, BoostType::SUPERCHARGER, "Parse \"SUPERCHARGER\" as BoostType");
assert_eq!("NITROUS".parse::<BoostType>()?, BoostType::NITROUS, "Parse \"NITROUS\" as BoostType");
assert_eq!("KERS".parse::<BoostType>()?, BoostType::KERS, "Parse \"KERS\" as BoostType");

assert_eq!("Turbo".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Turbo\" as BoostType");
assert_eq!("Supercharger".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Supercharger\" as BoostType");
assert_eq!("Nitrous".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Nitrous\" as BoostType");
assert_eq!("Kers".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Kers\" as BoostType");

assert_eq!("AA".parse::<BoostType>()?, BoostType::NullVal, "Parse \"AA\" as BoostType");
assert_eq!("".parse::<BoostType>().unwrap(), BoostType::NullVal, "Parse \"\" as BoostType");

Ok(())
}
14 changes: 14 additions & 0 deletions rust/tests/baseline_enum_into.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use examples_baseline::{
boost_type::BoostType,
};

#[test]
fn test_boost_type_from_str() -> Result<(), ()> {
assert_eq!(<BoostType as Into<u8>>::into(BoostType::TURBO), 84_u8, "BoostType::TURBO into value");
assert_eq!(<BoostType as Into<u8>>::into(BoostType::SUPERCHARGER), 83_u8, "BoostType::SUPERCHARGER into value");
assert_eq!(<BoostType as Into<u8>>::into(BoostType::NITROUS), 78_u8, "BoostType::NITROUS into value");
assert_eq!(<BoostType as Into<u8>>::into(BoostType::KERS), 75_u8, "BoostType::KERS into value");
assert_eq!(<BoostType as Into<u8>>::into(BoostType::NullVal), 0_u8, "BoostType::NullVal into value");

Ok(())
}
14 changes: 14 additions & 0 deletions rust/tests/baseline_enum_to_str.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use examples_baseline::{
boost_type::BoostType,
};

#[test]
fn test_boost_type_from_str() -> Result<(), ()> {
assert_eq!(format!("{}", BoostType::TURBO), "TURBO", "Display \"TURBO\"");
assert_eq!(format!("{}", BoostType::SUPERCHARGER), "SUPERCHARGER", "Display \"SUPERCHARGER\"");
assert_eq!(format!("{}", BoostType::NITROUS), "NITROUS", "Display \"NITROUS\"");
assert_eq!(format!("{}", BoostType::KERS), "KERS", "Display \"KERS\"");
assert_eq!(format!("{}", BoostType::NullVal), "NullVal", "Display \"NullVal\"");

Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,24 @@ private static void generateEnum(
indent(writer, 0, "}\n");

// From impl
generateFromImplForEnum(enumRustName, primitiveType, messageBody, writer);

// Into impl
generateIntoImplForEnum(enumRustName, primitiveType, messageBody, writer);

// FromStr impl
generateFromStrImplForEnum(enumRustName, primitiveType, messageBody, writer);

// Display impl
generateDisplayImplForEnum(enumRustName, primitiveType, messageBody, writer);
}

private static void generateFromImplForEnum(
final String enumRustName,
final String primitiveType,
final List<Token> messageBody,
final Appendable writer) throws IOException
{
indent(writer, 0, "impl From<%s> for %s {\n", primitiveType, enumRustName);
indent(writer, 1, "#[inline]\n");
indent(writer, 1, "fn from(v: %s) -> Self {\n", primitiveType);
Expand All @@ -1285,6 +1303,76 @@ private static void generateEnum(
indent(writer, 0, "}\n");
}

private static void generateIntoImplForEnum(
final String enumRustName,
final String primitiveType,
final List<Token> messageBody,
final Appendable writer) throws IOException
{
indent(writer, 0, "impl Into<%s> for %s {\n", primitiveType, enumRustName);
indent(writer, 1, "#[inline]\n");
indent(writer, 1, "fn into(self) -> %s {\n", primitiveType);
indent(writer, 2, "match self {\n");
for (final Token token : messageBody)
{
final Encoding encoding = token.encoding();
final String literal = generateRustLiteral(encoding.primitiveType(), encoding.constValue().toString());
indent(writer, 3, "Self::%s => %s, \n", token.name(), literal);
}
{
final Encoding encoding = messageBody.get(0).encoding();
final CharSequence nullVal = generateRustLiteral(encoding.primitiveType(),
encoding.applicableNullValue().toString());
indent(writer, 3, "Self::NullVal => %s,\n", nullVal);
}
indent(writer, 2, "}\n");
indent(writer, 1, "}\n");
indent(writer, 0, "}\n");
}

private static void generateFromStrImplForEnum(
final String enumRustName,
final String primitiveType,
final List<Token> messageBody,
final Appendable writer) throws IOException
{
indent(writer, 0, "impl core::str::FromStr for %s {\n", enumRustName);
indent(writer, 1, "type Err = ();\n\n");
indent(writer, 1, "#[inline]\n");
indent(writer, 1, "fn from_str(v: &str) -> core::result::Result<Self, Self::Err> {\n");
indent(writer, 2, "match v {\n");
for (final Token token : messageBody)
{
indent(writer, 3, "\"%1$s\" => core::result::Result::Ok(Self::%1$s), \n", token.name());
}
// default => NullVal
indent(writer, 3, "_ => core::result::Result::Ok(Self::NullVal),\n");
indent(writer, 2, "}\n");
indent(writer, 1, "}\n");
indent(writer, 0, "}\n");
}

private static void generateDisplayImplForEnum(
final String enumRustName,
final String primitiveType,
final List<Token> messageBody,
final Appendable writer) throws IOException
{
indent(writer, 0, "impl core::fmt::Display for %s {\n", enumRustName);
indent(writer, 1, "#[inline]\n");
indent(writer, 1, "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n");
indent(writer, 2, "match self {\n");
for (final Token token : messageBody)
{
indent(writer, 3, "Self::%1$s => write!(f, \"%1$s\"), \n", token.name());
}
// default => Err
indent(writer, 3, "Self::NullVal => write!(f, \"NullVal\"),\n");
indent(writer, 2, "}\n");
indent(writer, 1, "}\n");
indent(writer, 0, "}\n");
}

private static void generateComposites(
final String schemaVersionType,
final Ir ir,
Expand Down

0 comments on commit 320850d

Please sign in to comment.