Skip to content

Commit 320850d

Browse files
authored
[Rust] Enhance enum supporting fromstr and display and into (#1020)
* [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
1 parent 4484457 commit 320850d

File tree

4 files changed

+137
-0
lines changed

4 files changed

+137
-0
lines changed

rust/tests/baseline_enum_from_str.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use examples_baseline::{
2+
boost_type::BoostType,
3+
};
4+
5+
#[test]
6+
fn test_boost_type_from_str() -> Result<(), ()> {
7+
assert_eq!("TURBO".parse::<BoostType>()?, BoostType::TURBO, "Parse \"TURBO\" as BoostType");
8+
assert_eq!("SUPERCHARGER".parse::<BoostType>()?, BoostType::SUPERCHARGER, "Parse \"SUPERCHARGER\" as BoostType");
9+
assert_eq!("NITROUS".parse::<BoostType>()?, BoostType::NITROUS, "Parse \"NITROUS\" as BoostType");
10+
assert_eq!("KERS".parse::<BoostType>()?, BoostType::KERS, "Parse \"KERS\" as BoostType");
11+
12+
assert_eq!("Turbo".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Turbo\" as BoostType");
13+
assert_eq!("Supercharger".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Supercharger\" as BoostType");
14+
assert_eq!("Nitrous".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Nitrous\" as BoostType");
15+
assert_eq!("Kers".parse::<BoostType>()?, BoostType::NullVal, "Parse \"Kers\" as BoostType");
16+
17+
assert_eq!("AA".parse::<BoostType>()?, BoostType::NullVal, "Parse \"AA\" as BoostType");
18+
assert_eq!("".parse::<BoostType>().unwrap(), BoostType::NullVal, "Parse \"\" as BoostType");
19+
20+
Ok(())
21+
}

rust/tests/baseline_enum_into.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use examples_baseline::{
2+
boost_type::BoostType,
3+
};
4+
5+
#[test]
6+
fn test_boost_type_from_str() -> Result<(), ()> {
7+
assert_eq!(<BoostType as Into<u8>>::into(BoostType::TURBO), 84_u8, "BoostType::TURBO into value");
8+
assert_eq!(<BoostType as Into<u8>>::into(BoostType::SUPERCHARGER), 83_u8, "BoostType::SUPERCHARGER into value");
9+
assert_eq!(<BoostType as Into<u8>>::into(BoostType::NITROUS), 78_u8, "BoostType::NITROUS into value");
10+
assert_eq!(<BoostType as Into<u8>>::into(BoostType::KERS), 75_u8, "BoostType::KERS into value");
11+
assert_eq!(<BoostType as Into<u8>>::into(BoostType::NullVal), 0_u8, "BoostType::NullVal into value");
12+
13+
Ok(())
14+
}

rust/tests/baseline_enum_to_str.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use examples_baseline::{
2+
boost_type::BoostType,
3+
};
4+
5+
#[test]
6+
fn test_boost_type_from_str() -> Result<(), ()> {
7+
assert_eq!(format!("{}", BoostType::TURBO), "TURBO", "Display \"TURBO\"");
8+
assert_eq!(format!("{}", BoostType::SUPERCHARGER), "SUPERCHARGER", "Display \"SUPERCHARGER\"");
9+
assert_eq!(format!("{}", BoostType::NITROUS), "NITROUS", "Display \"NITROUS\"");
10+
assert_eq!(format!("{}", BoostType::KERS), "KERS", "Display \"KERS\"");
11+
assert_eq!(format!("{}", BoostType::NullVal), "NullVal", "Display \"NullVal\"");
12+
13+
Ok(())
14+
}

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/rust/RustGenerator.java

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,24 @@ private static void generateEnum(
12661266
indent(writer, 0, "}\n");
12671267

12681268
// From impl
1269+
generateFromImplForEnum(enumRustName, primitiveType, messageBody, writer);
1270+
1271+
// Into impl
1272+
generateIntoImplForEnum(enumRustName, primitiveType, messageBody, writer);
1273+
1274+
// FromStr impl
1275+
generateFromStrImplForEnum(enumRustName, primitiveType, messageBody, writer);
1276+
1277+
// Display impl
1278+
generateDisplayImplForEnum(enumRustName, primitiveType, messageBody, writer);
1279+
}
1280+
1281+
private static void generateFromImplForEnum(
1282+
final String enumRustName,
1283+
final String primitiveType,
1284+
final List<Token> messageBody,
1285+
final Appendable writer) throws IOException
1286+
{
12691287
indent(writer, 0, "impl From<%s> for %s {\n", primitiveType, enumRustName);
12701288
indent(writer, 1, "#[inline]\n");
12711289
indent(writer, 1, "fn from(v: %s) -> Self {\n", primitiveType);
@@ -1285,6 +1303,76 @@ private static void generateEnum(
12851303
indent(writer, 0, "}\n");
12861304
}
12871305

1306+
private static void generateIntoImplForEnum(
1307+
final String enumRustName,
1308+
final String primitiveType,
1309+
final List<Token> messageBody,
1310+
final Appendable writer) throws IOException
1311+
{
1312+
indent(writer, 0, "impl Into<%s> for %s {\n", primitiveType, enumRustName);
1313+
indent(writer, 1, "#[inline]\n");
1314+
indent(writer, 1, "fn into(self) -> %s {\n", primitiveType);
1315+
indent(writer, 2, "match self {\n");
1316+
for (final Token token : messageBody)
1317+
{
1318+
final Encoding encoding = token.encoding();
1319+
final String literal = generateRustLiteral(encoding.primitiveType(), encoding.constValue().toString());
1320+
indent(writer, 3, "Self::%s => %s, \n", token.name(), literal);
1321+
}
1322+
{
1323+
final Encoding encoding = messageBody.get(0).encoding();
1324+
final CharSequence nullVal = generateRustLiteral(encoding.primitiveType(),
1325+
encoding.applicableNullValue().toString());
1326+
indent(writer, 3, "Self::NullVal => %s,\n", nullVal);
1327+
}
1328+
indent(writer, 2, "}\n");
1329+
indent(writer, 1, "}\n");
1330+
indent(writer, 0, "}\n");
1331+
}
1332+
1333+
private static void generateFromStrImplForEnum(
1334+
final String enumRustName,
1335+
final String primitiveType,
1336+
final List<Token> messageBody,
1337+
final Appendable writer) throws IOException
1338+
{
1339+
indent(writer, 0, "impl core::str::FromStr for %s {\n", enumRustName);
1340+
indent(writer, 1, "type Err = ();\n\n");
1341+
indent(writer, 1, "#[inline]\n");
1342+
indent(writer, 1, "fn from_str(v: &str) -> core::result::Result<Self, Self::Err> {\n");
1343+
indent(writer, 2, "match v {\n");
1344+
for (final Token token : messageBody)
1345+
{
1346+
indent(writer, 3, "\"%1$s\" => core::result::Result::Ok(Self::%1$s), \n", token.name());
1347+
}
1348+
// default => NullVal
1349+
indent(writer, 3, "_ => core::result::Result::Ok(Self::NullVal),\n");
1350+
indent(writer, 2, "}\n");
1351+
indent(writer, 1, "}\n");
1352+
indent(writer, 0, "}\n");
1353+
}
1354+
1355+
private static void generateDisplayImplForEnum(
1356+
final String enumRustName,
1357+
final String primitiveType,
1358+
final List<Token> messageBody,
1359+
final Appendable writer) throws IOException
1360+
{
1361+
indent(writer, 0, "impl core::fmt::Display for %s {\n", enumRustName);
1362+
indent(writer, 1, "#[inline]\n");
1363+
indent(writer, 1, "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n");
1364+
indent(writer, 2, "match self {\n");
1365+
for (final Token token : messageBody)
1366+
{
1367+
indent(writer, 3, "Self::%1$s => write!(f, \"%1$s\"), \n", token.name());
1368+
}
1369+
// default => Err
1370+
indent(writer, 3, "Self::NullVal => write!(f, \"NullVal\"),\n");
1371+
indent(writer, 2, "}\n");
1372+
indent(writer, 1, "}\n");
1373+
indent(writer, 0, "}\n");
1374+
}
1375+
12881376
private static void generateComposites(
12891377
final String schemaVersionType,
12901378
final Ir ir,

0 commit comments

Comments
 (0)