in codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/HttpBoundProtocolGenerator.kt [167:237]
fun parseError(operationShape: OperationShape): RuntimeType {
val fnName = "parse_${operationShape.id.name.toSnakeCase()}_error"
val outputShape = operationShape.outputShape(model)
val outputSymbol = symbolProvider.toSymbol(outputShape)
val errorSymbol = operationShape.errorSymbol(symbolProvider)
return RuntimeType.forInlineFun(fnName, operationDeserModule) {
Attribute.Custom("allow(clippy::unnecessary_wraps)").render(it)
it.rustBlockTemplate(
"pub fn $fnName(response: &#{http}::Response<#{Bytes}>) -> std::result::Result<#{O}, #{E}>",
*codegenScope,
"O" to outputSymbol,
"E" to errorSymbol
) {
rust(
"let generic = #T(response).map_err(#T::unhandled)?;",
protocol.parseHttpGenericError(operationShape),
errorSymbol
)
if (operationShape.errors.isNotEmpty()) {
rustTemplate(
"""
let error_code = match generic.code() {
Some(code) => code,
None => return Err(#{error_symbol}::unhandled(generic))
};
let _error_message = generic.message().map(|msg|msg.to_owned());
""",
"error_symbol" to errorSymbol,
)
withBlock("Err(match error_code {", "})") {
operationShape.errors.forEach { error ->
val errorShape = model.expectShape(error, StructureShape::class.java)
val variantName = symbolProvider.toSymbol(model.expectShape(error)).name
val errorCode = httpBindingResolver.errorCode(errorShape).dq()
withBlock(
"$errorCode => #1T { meta: generic, kind: #1TKind::$variantName({",
"})},",
errorSymbol
) {
Attribute.AllowUnusedMut.render(this)
assignment("mut tmp") {
rustBlock("") {
renderShapeParser(
operationShape,
errorShape,
httpBindingResolver.errorResponseBindings(errorShape),
errorSymbol
)
}
}
if (errorShape.errorMessageMember() != null) {
rust(
"""
if (&tmp.message).is_none() {
tmp.message = _error_message;
}
"""
)
}
rust("tmp")
}
}
rust("_ => #T::generic(generic)", errorSymbol)
}
} else {
rust("Err(#T::generic(generic))", errorSymbol)
}
}
}
}