Skip to content

Commit

Permalink
Add POC code for constraint traits RFC
Browse files Browse the repository at this point in the history
  • Loading branch information
david-perez committed Feb 17, 2022
1 parent 306eccd commit 4963f06
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
86 changes: 86 additions & 0 deletions rust-runtime/aws-smithy-http-server/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use std::convert::TryFrom;

pub enum NiceStringValidationError {
/// Validation error holding the number of Unicode code points found, when a value between `1` and
/// `69` (inclusive) was expected.
LengthViolation(usize),
}

pub struct NiceString(String);

impl NiceString {
pub fn parse(inner: String) -> Result<Self, NiceStringValidationError> {
Self::try_from(inner)
}
}

impl TryFrom<String> for NiceString {
type Error = NiceStringValidationError;

fn try_from(value: String) -> Result<Self, Self::Error> {
let num_code_points = value.chars().count();
if 1 <= num_code_points && num_code_points <= 69 {
Ok(Self(value))
} else {
Err(NiceStringValidationError::LengthViolation(num_code_points))
}
}
}

// This implementation is used when formatting the error in the 400 HTTP response body, among other
// places.
// The format of the error messages will not be configurable by service implementers and its format
// will be:
//
// `<StructName>` validation error: <constraint> violation: <message>
//
// where:
// * <StructName> is the name of the generated struct,
// * <constraint> is the name of the violated Smithy constraint; and
// * <message> is a templated message specific to the particular constraint instantiation (so
// e.g. `@length(min: 1)` may have a different template than `@length(min: 1, max: 69)`.
//
// If the shape is marked with `@sensitive`, the format of the message will be:
//
// `<StructName` validation error
impl std::fmt::Display for NiceStringValidationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
NiceStringValidationError::LengthViolation(found) => write!(
f,
"MyStruct validation error: length violation: expected value between 1 and 69, but found {}",
found
),
}
}
}

// This is the `Debug` implementation if the shape is marked with `@sensitive`.
// If the shape is not marked with `@sensitive`, we will just `#[derive(Debug)]`.
impl std::fmt::Debug for NiceStringValidationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut formatter = f.debug_struct("NiceStringValidationError");
formatter.finish()
}
}

impl std::error::Error for NiceStringValidationError {}

// pub(crate) struct MyStructValidationErrorWrapper(MyStructValidationError);

// impl axum_core::response::IntoResponse for MyStructValidationErrorWrapper {
// fn into_response(self) -> axum_core::response::Response {
// let err = MyStructValidationError::LengthViolation(70);
// let rejection = aws_smithy_http_server::rejection::SmithyRejection::ConstraintViolation(
// aws_smithy_http_server::rejection::ConstraintViolation::from_err(err),
// );
// rejection.into_response()
// }
// }

pub fn main() {
let err = NiceStringValidationError::LengthViolation(70);
let constraint_rejection = aws_smithy_http_server::rejection::ConstraintViolation::from_err(err);
let deserialize_rejection = aws_smithy_http_server::rejection::Deserialize::from_err(constraint_rejection);
let smithy_rejection = aws_smithy_http_server::rejection::SmithyRejection::Deserialize(deserialize_rejection);
}
6 changes: 6 additions & 0 deletions rust-runtime/aws-smithy-http-server/src/rejection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ define_rejection! {
pub struct MissingExtension(Error);
}

define_rejection! {
#[status = BAD_REQUEST]
#[body = "Constraint violation"]
pub struct ConstraintViolation(Error);
}

composite_rejection! {
/// Rejection used for `Content-Type` errors such as missing `Content-Type`
/// header, MIME parse issues, etc.
Expand Down

0 comments on commit 4963f06

Please sign in to comment.