Skip to content

Commit

Permalink
Default trait in server
Browse files Browse the repository at this point in the history
Signed-off-by: Daniele Ahmed <[email protected]>
  • Loading branch information
82marbag authored and Daniele Ahmed committed Dec 20, 2022
1 parent 59de022 commit 77d5a51
Show file tree
Hide file tree
Showing 9 changed files with 608 additions and 160 deletions.
2 changes: 1 addition & 1 deletion codegen-core/common-test-models/constraints.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ string LengthPatternString
@length(min: 1, max: 69)
string MediaTypeLengthString

@range(min: -0, max: 69)
@range(min: -7, max: 69)
integer RangeInteger

@range(min: -10)
Expand Down
126 changes: 12 additions & 114 deletions codegen-core/common-test-models/simple.smithy
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
$version: "1.0"
$version: "2.0"

namespace com.amazonaws.simple

Expand All @@ -12,125 +12,23 @@ use smithy.framework#ValidationException
@documentation("A simple service example, with a Service resource that can be registered and a readonly healthcheck")
service SimpleService {
version: "2022-01-01",
resources: [
Service,
],
operations: [
Healthcheck,
StoreServiceBlob,
HealthCheck,
],
}

@documentation("Id of the service that will be registered")
string ServiceId

@documentation("Name of the service that will be registered")
string ServiceName

@error("client")
@documentation(
"""
Returned when a new resource cannot be created because one already exists.
"""
)
structure ResourceAlreadyExists {
@required
message: String
}

@documentation("A resource that can register services")
resource Service {
identifiers: { id: ServiceId },
put: RegisterService,
}

@idempotent
@http(method: "PUT", uri: "/service/{id}")
@documentation("Service register operation")
@httpRequestTests([
{
id: "RegisterServiceRequestTest",
protocol: "aws.protocols#restJson1",
uri: "/service/1",
headers: {
"Content-Type": "application/json",
},
params: { id: "1", name: "TestService" },
body: "{\"name\":\"TestService\"}",
method: "PUT",
}
])
@httpResponseTests([
{
id: "RegisterServiceResponseTest",
protocol: "aws.protocols#restJson1",
params: { id: "1", name: "TestService" },
body: "{\"id\":\"1\",\"name\":\"TestService\"}",
code: 200,
headers: {
"Content-Length": "31"
}
}
])
operation RegisterService {
input: RegisterServiceInputRequest,
output: RegisterServiceOutputResponse,
errors: [ResourceAlreadyExists, ValidationException]
}

@documentation("Service register input structure")
structure RegisterServiceInputRequest {
@required
@httpLabel
id: ServiceId,
name: ServiceName,
}

@documentation("Service register output structure")
structure RegisterServiceOutputResponse {
@required
id: ServiceId,
name: ServiceName,
}

@readonly
@http(uri: "/healthcheck", method: "GET")
@documentation("Read-only healthcheck operation")
operation Healthcheck {
input: HealthcheckInputRequest,
output: HealthcheckOutputResponse
}

@documentation("Service healthcheck output structure")
structure HealthcheckInputRequest {

}

@documentation("Service healthcheck input structure")
structure HealthcheckOutputResponse {

}

@readonly
@http(method: "POST", uri: "/service/{id}/blob")
@documentation("Stores a blob for a service id")
operation StoreServiceBlob {
input: StoreServiceBlobInput,
output: StoreServiceBlobOutput,
@http(uri: "/", method: "POST")
operation HealthCheck {
input: Input,
errors: [ValidationException]
}

@documentation("Store a blob for a service id input structure")
structure StoreServiceBlobInput {
@required
@httpLabel
id: ServiceId,
@required
@httpPayload
content: Blob,
@input
structure Input {
@default(15)
int:ConstrainedInteger
}

@documentation("Store a blob for a service id output structure")
structure StoreServiceBlobOutput {

}
@default(15)
@range(min: 10, max: 29)
integer ConstrainedInteger
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ fun Shape.isDirectlyConstrained(symbolProvider: SymbolProvider): Boolean = when
}

fun MemberShape.hasConstraintTraitOrTargetHasConstraintTrait(model: Model, symbolProvider: SymbolProvider): Boolean =
this.isDirectlyConstrained(symbolProvider) || (model.expectShape(this.target).isDirectlyConstrained(symbolProvider))
this.isDirectlyConstrained(symbolProvider) || model.expectShape(this.target).isDirectlyConstrained(symbolProvider)

fun Shape.isTransitivelyButNotDirectlyConstrained(model: Model, symbolProvider: SymbolProvider): Boolean =
!this.isDirectlyConstrained(symbolProvider) && this.canReachConstrainedShape(model, symbolProvider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ object ServerCargoDependency {
val Regex: CargoDependency = CargoDependency("regex", CratesIo("1.5.5"))

fun smithyHttpServer(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-http-server")
fun smithyTypes(runtimeConfig: RuntimeConfig) = runtimeConfig.smithyRuntimeCrate("smithy-types")
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,16 @@ class ServerBuilderConstraintViolations(
nonExhaustive: Boolean,
shouldRenderAsValidationExceptionFieldList: Boolean,
) {
check(all.isNotEmpty())

Attribute.Derives(setOf(RuntimeType.Debug, RuntimeType.PartialEq)).render(writer)
writer.docs("Holds one variant for each of the ways the builder can fail.")
if (nonExhaustive) Attribute.NonExhaustive.render(writer)
val constraintViolationSymbolName = constraintViolationSymbolProvider.toSymbol(shape).name
writer.rustBlock("pub${ if (visibility == Visibility.PUBCRATE) " (crate) " else "" } enum $constraintViolationSymbolName") {
writer.rustBlock("pub${if (visibility == Visibility.PUBCRATE) " (crate) " else ""} enum $constraintViolationSymbolName") {
renderConstraintViolations(writer)
}

renderImplDisplayConstraintViolation(writer)
writer.rust("impl #T for ConstraintViolation { }", RuntimeType.StdError)

Expand All @@ -93,7 +96,7 @@ class ServerBuilderConstraintViolations(
fun forMember(member: MemberShape): ConstraintViolation? {
check(members.contains(member))
// TODO(https://github.com/awslabs/smithy-rs/issues/1302, https://github.com/awslabs/smithy/issues/1179): See above.
return if (symbolProvider.toSymbol(member).isOptional()) {
return if (symbolProvider.toSymbol(member).isOptional() || member.hasNonNullDefault()) {
null
} else {
ConstraintViolation(member, ConstraintViolationKind.MISSING_MEMBER)
Expand Down
Loading

0 comments on commit 77d5a51

Please sign in to comment.