Skip to content

Commit 5fd7eaa

Browse files
author
Fahad Zubair
committed
Additional files added to git
1 parent 57c9306 commit 5fd7eaa

File tree

4 files changed

+118
-11
lines changed

4 files changed

+118
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package software.amazon.smithy.rust.codegen.core.smithy.traits
2+
3+
import software.amazon.smithy.model.node.Node
4+
import software.amazon.smithy.model.shapes.ShapeId
5+
import software.amazon.smithy.model.traits.AnnotationTrait
6+
7+
class SyntheticImplDisplayTrait : AnnotationTrait(ID, Node.objectNode()) {
8+
companion object {
9+
val ID: ShapeId = ShapeId.from("software.amazon.smithy.rust.codegen.core.smithy.traits#syntheticImplDisplayTrait")
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package software.amazon.smithy.rust.codegen.core.smithy.transformers
2+
3+
import software.amazon.smithy.model.Model
4+
import software.amazon.smithy.model.shapes.AbstractShapeBuilder
5+
import software.amazon.smithy.model.shapes.EnumShape
6+
import software.amazon.smithy.model.shapes.ListShape
7+
import software.amazon.smithy.model.shapes.MapShape
8+
import software.amazon.smithy.model.shapes.StructureShape
9+
import software.amazon.smithy.model.shapes.UnionShape
10+
import software.amazon.smithy.model.traits.ErrorTrait
11+
import software.amazon.smithy.model.transform.ModelTransformer
12+
import software.amazon.smithy.rust.codegen.core.smithy.DirectedWalker
13+
import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticImplDisplayTrait
14+
import software.amazon.smithy.rust.codegen.core.util.UNREACHABLE
15+
import software.amazon.smithy.rust.codegen.core.util.getTrait
16+
import software.amazon.smithy.utils.ToSmithyBuilder
17+
18+
/**
19+
* Adds a synthetic trait to shapes that are reachable from error shapes to ensure they
20+
* implement the `Display` trait in generated code.
21+
*
22+
* When a shape is annotated with `@error`, it needs to implement Rust's `Display` trait.
23+
* If the error shape contains references to other structures, those structures also
24+
* need to implement `Display` for proper error formatting.
25+
*/
26+
object AddSyntheticTraitForImplDisplay {
27+
/**
28+
* Transforms the model by adding [SyntheticImplDisplayTrait] to all shapes that are:
29+
* 1. Reachable from an error shape
30+
* 2. Not already marked with `@error`
31+
* 3. Of a type that can implement `Display` (structure, list, union, or map)
32+
*
33+
* @param model The input model to transform
34+
* @return The transformed model with synthetic traits added
35+
*/
36+
fun transform(model: Model): Model {
37+
val walker = DirectedWalker(model)
38+
39+
// Find all error shapes from operations.
40+
val errorShapes =
41+
model.operationShapes
42+
.flatMap { it.errors }
43+
.mapNotNull { model.expectShape(it).asStructureShape().orElse(null) }
44+
45+
// Get shapes reachable from error shapes that need Display impl.
46+
val shapesNeedingDisplay =
47+
errorShapes
48+
.flatMap { walker.walkShapes(it) }
49+
.filter {
50+
(it is StructureShape || it is ListShape || it is UnionShape || it is MapShape || it is EnumShape) &&
51+
it.getTrait<ErrorTrait>() == null
52+
}
53+
54+
// Add synthetic trait to identified shapes.
55+
val transformedShapes =
56+
shapesNeedingDisplay.mapNotNull { shape ->
57+
if (shape !is ToSmithyBuilder<*>) {
58+
UNREACHABLE("Shapes reachable from error shapes should be buildable")
59+
return@mapNotNull null
60+
}
61+
62+
val builder = shape.toBuilder()
63+
if (builder is AbstractShapeBuilder<*, *>) {
64+
builder.addTrait(SyntheticImplDisplayTrait()).build()
65+
} else {
66+
UNREACHABLE("`impl Display` cannot be generated for ${shape.id}")
67+
null
68+
}
69+
}
70+
71+
return ModelTransformer.create().replaceShapes(model, transformedShapes)
72+
}
73+
}

codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerEnumGenerator.kt

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,27 @@ class PythonConstrainedEnum(
5959
}
6060

6161
private fun pyEnumName(context: EnumGeneratorContext): Writable =
62-
writable {
63-
rustBlock(
64-
"""
65-
##[getter]
66-
pub fn name(&self) -> &str
67-
""",
68-
) {
69-
rustBlock("match self") {
70-
context.sortedMembers.forEach { member ->
71-
val memberName = member.name()?.name
72-
rust("""${context.enumName}::$memberName => ${memberName?.dq()},""")
62+
// Only named enums have a `name` property. Do not generate `fn name` for
63+
// unnamed enums.
64+
if (context.enumTrait.hasNames()) {
65+
writable {
66+
rustBlock(
67+
"""
68+
##[getter]
69+
pub fn name(&self) -> &str
70+
""",
71+
) {
72+
rustBlock("match self") {
73+
context.sortedMembers.forEach { member ->
74+
val memberName = member.name()?.name
75+
check(memberName != null) { "${context.enumTrait} cannot have null members" }
76+
rust("""${context.enumName}::$memberName => ${memberName?.dq()},""")
77+
}
7378
}
7479
}
7580
}
81+
} else {
82+
writable {}
7683
}
7784
}
7885

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package software.amazon.smithy.rust.codegen.server.smithy.generators
2+
3+
import org.junit.jupiter.api.Test
4+
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
5+
import software.amazon.smithy.rust.codegen.server.smithy.testutil.serverIntegrationTest
6+
import java.io.File
7+
8+
class ServerErrorReachableShapesDisplayTest {
9+
@Test
10+
fun `composite error shapes are compilable`() {
11+
var sampleModel = File("../codegen-core/common-test-models/nested-error.smithy").readText().asSmithyModel()
12+
serverIntegrationTest(sampleModel) { _, _ ->
13+
// It should compile.
14+
}
15+
}
16+
}

0 commit comments

Comments
 (0)