From 336d788336b43b8699936cda5704917150db49a0 Mon Sep 17 00:00:00 2001 From: Alex Chew Date: Wed, 25 Sep 2024 17:10:22 -0700 Subject: [PATCH] feat: Rust codegen for Constraints (#582) *Issue #, if available:* #533 *Description of changes:* This PR implements Rust library codegen for input validation of supported constraint traits (`@required`, `@length`, `@range`). Notes: * Unlike in Java and C#, library users may directly construct the generated operation input structures in Rust (in order to aid in idiomatic usage, especially w.r.t. pattern matching, like the AWS SDK for Rust does) and are not restricted to using the builder pattern. Therefore, the builder can't take sole responsibility for validation; instead, validation happens whenever an operation is called. * Unlike other target languages, Rust is limited in its ability to propagate arbitrary errors up the call stack unless the API is designed for doing so. Our models don't define a specific error shape for validation, so in order to represent validation errors in the generated `Error` enum, we generate a `ValidationError` variant that only exists on the Rust side. When converting to Dafny, we upcast the error into the `Opaque` variant; when converting from Dafny, we downcast it back after checking that doing so is safe using `dafny_runtime::is_object!`. * By Polymorph's design, values crossing the boundary from Dafny-compiled code are assumed to be "valid", but the `WrappedSimpleConstraintsTest` intentionally breaks this assumption in order to test the constraint validation logic, forcing invalid values across the boundary by (ab)using `{:axiom}`. This would be okay except that the Dafny tests in the Constraints test model *also* pass across malformed UTF-8 for `@DafnyUtf8Bytes` strings (which is not a constraint trait). The Rust type conversion process does not allow for failure when converting values from Dafny (doing so would be a major refactor and probably some performance impact), so I've isolated the malformed UTF-8 test assertions and used a bit of `sed` to simply disable them for Rust specifically, while allowing the other languages to continue testing them. --- TestModels/Constraints/Makefile | 22 +- .../Constraints/runtimes/rust/Cargo.toml | 25 + .../Constraints/runtimes/rust/src/client.rs | 38 ++ .../rust/src/client/get_constraints.rs | 49 ++ .../runtimes/rust/src/conversions.rs | 10 + .../runtimes/rust/src/conversions/client.rs | 24 + .../runtimes/rust/src/conversions/error.rs | 99 ++++ .../rust/src/conversions/get_constraints.rs | 6 + .../get_constraints/_get_constraints_input.rs | 192 ++++++++ .../_get_constraints_output.rs | 192 ++++++++ .../conversions/simple_constraints_config.rs | 4 + .../_simple_constraints_config.rs | 44 ++ .../Constraints/runtimes/rust/src/error.rs | 16 + .../rust/src/error/sealed_unhandled.rs | 32 ++ .../runtimes/rust/src/operation.rs | 5 + .../rust/src/operation/get_constraints.rs | 156 +++++++ .../get_constraints/_get_constraints_input.rs | 432 ++++++++++++++++++ .../_get_constraints_output.rs | 432 ++++++++++++++++++ .../src/operation/get_constraints/builders.rs | 313 +++++++++++++ .../rust/src/standard_library_conversions.rs | 266 +++++++++++ .../rust/src/standard_library_externs.rs | 80 ++++ .../Constraints/runtimes/rust/src/types.rs | 16 + .../runtimes/rust/src/types/builders.rs | 3 + .../runtimes/rust/src/types/error.rs | 67 +++ .../src/types/simple_constraints_config.rs | 41 ++ .../Constraints/runtimes/rust/src/wrapped.rs | 15 + .../runtimes/rust/src/wrapped/client.rs | 83 ++++ .../rust/tests/simple_constraints_test.rs | 69 +++ .../test/WrappedSimpleConstraintsTest.dfy | 40 +- .../runtimes/rust/src/conversions/error.rs | 27 ++ .../runtimes/rust/src/operation/get_name.rs | 2 + .../rust/src/operation/get_resource.rs | 7 + .../src/operation/get_resource_positional.rs | 7 + .../runtimes/rust/src/types/error.rs | 47 +- .../generator/AbstractRustShimGenerator.java | 5 +- .../generator/RustLibraryShimGenerator.java | 195 ++++++-- .../polymorph/utils/ConstrainTraitUtils.java | 75 ++- .../rust/conversions/error_library.rs | 27 ++ .../runtimes/rust/operation/outer.rs | 2 + .../templates/runtimes/rust/types/error.rs | 47 +- 40 files changed, 3162 insertions(+), 50 deletions(-) create mode 100644 TestModels/Constraints/runtimes/rust/Cargo.toml create mode 100644 TestModels/Constraints/runtimes/rust/src/client.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/client/get_constraints.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions/client.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions/error.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions/get_constraints.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_input.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_output.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config/_simple_constraints_config.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/error.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/error/sealed_unhandled.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/operation.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/operation/get_constraints.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_input.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_output.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/operation/get_constraints/builders.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/standard_library_conversions.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/standard_library_externs.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/types.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/types/builders.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/types/error.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/types/simple_constraints_config.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/wrapped.rs create mode 100644 TestModels/Constraints/runtimes/rust/src/wrapped/client.rs create mode 100644 TestModels/Constraints/runtimes/rust/tests/simple_constraints_test.rs diff --git a/TestModels/Constraints/Makefile b/TestModels/Constraints/Makefile index 860e1e5b8..88fd6b95b 100644 --- a/TestModels/Constraints/Makefile +++ b/TestModels/Constraints/Makefile @@ -5,6 +5,8 @@ CORES=2 ENABLE_EXTERN_PROCESSING=1 +TRANSPILE_TESTS_IN_RUST=1 + include ../SharedMakefile.mk PROJECT_SERVICES := \ @@ -19,13 +21,19 @@ SMITHY_DEPS=dafny-dependencies/Model/traits.smithy # This project has no dependencies # DEPENDENT-MODELS:= -# First, export DAFNY_VERSION=4.2 -# Three separate items, because 'make polymorph_code_gen' doesn't quite work -polymorph: - npm i --no-save prettier@3 prettier-plugin-java@2.5 - make polymorph_dafny - make polymorph_java - make polymorph_dotnet +clean: _clean + rm -rf $(LIBRARY_ROOT)/runtimes/java/src/main/dafny-generated + rm -rf $(LIBRARY_ROOT)/runtimes/java/src/main/smithy-generated + rm -rf $(LIBRARY_ROOT)/runtimes/java/src/test/dafny-generated + +# Patch out tests that Rust codegen doesn't support +transpile_rust: | transpile_implementation_rust transpile_dependencies_rust remove_unsupported_rust_tests + +remove_unsupported_rust_tests: + $(MAKE) _sed_file \ + SED_FILE_PATH=$(LIBRARY_ROOT)/runtimes/rust/src/implementation_from_dafny.rs \ + SED_BEFORE_STRING='let mut allowBadUtf8BytesFromDafny: bool = true' \ + SED_AFTER_STRING='let mut allowBadUtf8BytesFromDafny: bool = false' # Python diff --git a/TestModels/Constraints/runtimes/rust/Cargo.toml b/TestModels/Constraints/runtimes/rust/Cargo.toml new file mode 100644 index 000000000..c970b51fd --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "simple_constraints" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +wrapped-client = [] + +[dependencies] +aws-smithy-runtime = {version = "1.7.1", features=["client"]} +aws-smithy-runtime-api = {version = "1.7.2", features=["client"]} +aws-smithy-types = "1.2.4" +dafny_runtime = { path = "../../../dafny-dependencies/dafny_runtime_rust"} + +[dependencies.tokio] +version = "1.26.0" +features = ["full"] + +[dev-dependencies] +simple_constraints = { path = ".", features = ["wrapped-client"] } + +[lib] +path = "src/implementation_from_dafny.rs" diff --git a/TestModels/Constraints/runtimes/rust/src/client.rs b/TestModels/Constraints/runtimes/rust/src/client.rs new file mode 100644 index 000000000..e1bd88f54 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/client.rs @@ -0,0 +1,38 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +use aws_smithy_types::error::operation::BuildError; + +#[derive(::std::clone::Clone, ::std::fmt::Debug, ::std::cmp::PartialEq)] +pub struct Client { + pub(crate) dafny_client: ::dafny_runtime::Object +} + +impl Client { + /// Creates a new client from the service [`Config`](crate::Config). + #[track_caller] + pub fn from_conf( + conf: crate::types::simple_constraints_config::SimpleConstraintsConfig, + ) -> Result { + let inner = + crate::simple::constraints::internaldafny::_default::SimpleConstraints( + &crate::conversions::simple_constraints_config::_simple_constraints_config::to_dafny(conf), + ); + if matches!( + inner.as_ref(), + crate::_Wrappers_Compile::Result::Failure { .. } + ) { + // TODO: convert error - the potential types are not modeled! + return Err(BuildError::other( + ::aws_smithy_types::error::metadata::ErrorMetadata::builder() + .message("Invalid client config") + .build(), + )); + } + Ok(Self { + dafny_client: ::dafny_runtime::upcast_object()(inner.Extract()) + }) + } +} + +mod get_constraints; diff --git a/TestModels/Constraints/runtimes/rust/src/client/get_constraints.rs b/TestModels/Constraints/runtimes/rust/src/client/get_constraints.rs new file mode 100644 index 000000000..ea2529f18 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/client/get_constraints.rs @@ -0,0 +1,49 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +impl crate::client::Client { + /// Constructs a fluent builder for the [`GetConstraints`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder) operation. + /// + /// - The fluent builder is configurable: + /// - [`blob_less_than_or_equal_to_ten(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::blob_less_than_or_equal_to_ten) / [`set_blob_less_than_or_equal_to_ten(Option<::aws_smithy_types::Blob>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_blob_less_than_or_equal_to_ten): (undocumented)
+ /// - [`greater_than_one(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::greater_than_one) / [`set_greater_than_one(Option<::std::primitive::i32>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_greater_than_one): (undocumented)
+ /// - [`less_than_ten(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::less_than_ten) / [`set_less_than_ten(Option<::std::primitive::i32>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_less_than_ten): (undocumented)
+ /// - [`list_less_than_or_equal_to_ten(impl Into>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::list_less_than_or_equal_to_ten) / [`set_list_less_than_or_equal_to_ten(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_list_less_than_or_equal_to_ten): (undocumented)
+ /// - [`map_less_than_or_equal_to_ten(impl Into>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::map_less_than_or_equal_to_ten) / [`set_map_less_than_or_equal_to_ten(Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_map_less_than_or_equal_to_ten): (undocumented)
+ /// - [`my_blob(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::my_blob) / [`set_my_blob(Option<::aws_smithy_types::Blob>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_my_blob): (undocumented)
+ /// - [`my_list(impl Into>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::my_list) / [`set_my_list(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_my_list): (undocumented)
+ /// - [`my_list_of_utf8_bytes(impl Into>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::my_list_of_utf8_bytes) / [`set_my_list_of_utf8_bytes(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_my_list_of_utf8_bytes): (undocumented)
+ /// - [`my_map(impl Into>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::my_map) / [`set_my_map(Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_my_map): (undocumented)
+ /// - [`my_string(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::my_string) / [`set_my_string(Option<::std::string::String>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_my_string): (undocumented)
+ /// - [`my_utf8_bytes(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::my_utf8_bytes) / [`set_my_utf8_bytes(Option<::std::string::String>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_my_utf8_bytes): (undocumented)
+ /// - [`non_empty_blob(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::non_empty_blob) / [`set_non_empty_blob(Option<::aws_smithy_types::Blob>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_non_empty_blob): (undocumented)
+ /// - [`non_empty_list(impl Into>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::non_empty_list) / [`set_non_empty_list(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_non_empty_list): (undocumented)
+ /// - [`non_empty_map(impl Into>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::non_empty_map) / [`set_non_empty_map(Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_non_empty_map): (undocumented)
+ /// - [`non_empty_string(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::non_empty_string) / [`set_non_empty_string(Option<::std::string::String>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_non_empty_string): (undocumented)
+ /// - [`one_to_ten(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::one_to_ten) / [`set_one_to_ten(Option<::std::primitive::i32>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_one_to_ten): (undocumented)
+ /// - [`string_less_than_or_equal_to_ten(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::string_less_than_or_equal_to_ten) / [`set_string_less_than_or_equal_to_ten(Option<::std::string::String>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_string_less_than_or_equal_to_ten): (undocumented)
+ /// - [`my_ten_to_ten(impl Into>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::my_ten_to_ten) / [`set_my_ten_to_ten(Option<::std::primitive::i64>)`](crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::set_my_ten_to_ten): (undocumented)
+ /// - On success, responds with [`GetConstraintsOutput`](crate::operation::get_constraints::GetConstraintsOutput) with field(s): + /// - [`blob_less_than_or_equal_to_ten(Option<::aws_smithy_types::Blob>)`](crate::operation::get_constraints::GetConstraintsOutput::blob_less_than_or_equal_to_ten): (undocumented) + /// - [`greater_than_one(Option<::std::primitive::i32>)`](crate::operation::get_constraints::GetConstraintsOutput::greater_than_one): (undocumented) + /// - [`less_than_ten(Option<::std::primitive::i32>)`](crate::operation::get_constraints::GetConstraintsOutput::less_than_ten): (undocumented) + /// - [`list_less_than_or_equal_to_ten(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::GetConstraintsOutput::list_less_than_or_equal_to_ten): (undocumented) + /// - [`map_less_than_or_equal_to_ten(Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>)`](crate::operation::get_constraints::GetConstraintsOutput::map_less_than_or_equal_to_ten): (undocumented) + /// - [`my_blob(Option<::aws_smithy_types::Blob>)`](crate::operation::get_constraints::GetConstraintsOutput::my_blob): (undocumented) + /// - [`my_list(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::GetConstraintsOutput::my_list): (undocumented) + /// - [`my_list_of_utf8_bytes(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::GetConstraintsOutput::my_list_of_utf8_bytes): (undocumented) + /// - [`my_map(Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>)`](crate::operation::get_constraints::GetConstraintsOutput::my_map): (undocumented) + /// - [`my_string(Option<::std::string::String>)`](crate::operation::get_constraints::GetConstraintsOutput::my_string): (undocumented) + /// - [`my_utf8_bytes(Option<::std::string::String>)`](crate::operation::get_constraints::GetConstraintsOutput::my_utf8_bytes): (undocumented) + /// - [`non_empty_blob(Option<::aws_smithy_types::Blob>)`](crate::operation::get_constraints::GetConstraintsOutput::non_empty_blob): (undocumented) + /// - [`non_empty_list(Option<::std::vec::Vec<::std::string::String>>)`](crate::operation::get_constraints::GetConstraintsOutput::non_empty_list): (undocumented) + /// - [`non_empty_map(Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>)`](crate::operation::get_constraints::GetConstraintsOutput::non_empty_map): (undocumented) + /// - [`non_empty_string(Option<::std::string::String>)`](crate::operation::get_constraints::GetConstraintsOutput::non_empty_string): (undocumented) + /// - [`one_to_ten(Option<::std::primitive::i32>)`](crate::operation::get_constraints::GetConstraintsOutput::one_to_ten): (undocumented) + /// - [`string_less_than_or_equal_to_ten(Option<::std::string::String>)`](crate::operation::get_constraints::GetConstraintsOutput::string_less_than_or_equal_to_ten): (undocumented) + /// - [`that_ten_to_ten(Option<::std::primitive::i64>)`](crate::operation::get_constraints::GetConstraintsOutput::that_ten_to_ten): (undocumented) + /// - On failure, responds with [`SdkError`](crate::operation::get_constraints::GetConstraintsError) + pub fn get_constraints(&self) -> crate::operation::get_constraints::builders::GetConstraintsFluentBuilder { + crate::operation::get_constraints::builders::GetConstraintsFluentBuilder::new(self.clone()) + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/conversions.rs b/TestModels/Constraints/runtimes/rust/src/conversions.rs new file mode 100644 index 000000000..542f376cb --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions.rs @@ -0,0 +1,10 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +pub mod client; + + pub mod error; + + pub mod get_constraints; + +pub mod simple_constraints_config; diff --git a/TestModels/Constraints/runtimes/rust/src/conversions/client.rs b/TestModels/Constraints/runtimes/rust/src/conversions/client.rs new file mode 100644 index 000000000..2e457a513 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions/client.rs @@ -0,0 +1,24 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[allow(dead_code)] + +pub fn to_dafny( + value: &crate::client::Client, +) -> + ::dafny_runtime::Object +{ + value.dafny_client.clone() +} + +#[allow(dead_code)] +pub fn from_dafny( + dafny_value: ::dafny_runtime::Object< + dyn crate::r#simple::constraints::internaldafny::types::ISimpleConstraintsClient + >, +) -> crate::client::Client { + crate::client::Client { dafny_client: dafny_value } +} diff --git a/TestModels/Constraints/runtimes/rust/src/conversions/error.rs b/TestModels/Constraints/runtimes/rust/src/conversions/error.rs new file mode 100644 index 000000000..b45ea6156 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions/error.rs @@ -0,0 +1,99 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +/// Wraps up an arbitrary Rust Error value as a Dafny Error +pub fn to_opaque_error(value: E) -> + ::std::rc::Rc +{ + let error_obj: ::dafny_runtime::Object = ::dafny_runtime::Object(Some( + ::std::rc::Rc::new(::std::cell::UnsafeCell::new(value)), + )); + ::std::rc::Rc::new( + crate::r#simple::constraints::internaldafny::types::Error::Opaque { + obj: error_obj, + }, + ) +} + +/// Wraps up an arbitrary Rust Error value as a Dafny Result.Failure +pub fn to_opaque_error_result(value: E) -> + ::std::rc::Rc< + crate::_Wrappers_Compile::Result< + T, + ::std::rc::Rc + > + > +{ + ::std::rc::Rc::new(crate::_Wrappers_Compile::Result::Failure { + error: to_opaque_error(value), + }) +} +pub fn to_dafny( + value: crate::types::error::Error, +) -> ::std::rc::Rc { + ::std::rc::Rc::new(match value { + crate::types::error::Error::SimpleConstraintsException { message } => + crate::r#simple::constraints::internaldafny::types::Error::SimpleConstraintsException { + message: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&message), + }, + crate::types::error::Error::CollectionOfErrors { list, message } => + crate::r#simple::constraints::internaldafny::types::Error::CollectionOfErrors { + message: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&message), + list: ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&list, |e| to_dafny(e.clone())) + }, + crate::types::error::Error::ValidationError(inner) => + crate::r#simple::constraints::internaldafny::types::Error::Opaque { + obj: { + let rc = ::std::rc::Rc::new(inner) as ::std::rc::Rc; + // safety: `rc` is new, ensuring it has refcount 1 and is uniquely owned. + // we should use `dafny_runtime_conversions::rc_struct_to_dafny_class` once it + // accepts unsized types (https://github.com/dafny-lang/dafny/pull/5769) + unsafe { ::dafny_runtime::Object::from_rc(rc) } + }, + }, + crate::types::error::Error::Opaque { obj } => + crate::r#simple::constraints::internaldafny::types::Error::Opaque { + obj: ::dafny_runtime::Object(obj.0) + }, + }) +} + +#[allow(dead_code)] +pub fn from_dafny( + dafny_value: ::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::Error, + >, +) -> crate::types::error::Error { + match ::std::borrow::Borrow::borrow(&dafny_value) { + crate::r#simple::constraints::internaldafny::types::Error::SimpleConstraintsException { message } => + crate::types::error::Error::SimpleConstraintsException { + message: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(&message), + }, + crate::r#simple::constraints::internaldafny::types::Error::CollectionOfErrors { list, message } => + crate::types::error::Error::CollectionOfErrors { + message: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(&message), + list: ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(&list, |e| from_dafny(e.clone())) + }, + crate::r#simple::constraints::internaldafny::types::Error::Opaque { obj } => + crate::types::error::Error::Opaque { + obj: obj.clone() + }, + crate::r#simple::constraints::internaldafny::types::Error::Opaque { obj } => + { + use ::std::any::Any; + if ::dafny_runtime::is_object!(obj, crate::types::error::ValidationError) { + let typed = ::dafny_runtime::cast_object!(obj.clone(), crate::types::error::ValidationError); + crate::types::error::Error::ValidationError( + // safety: dafny_class_to_struct will increment ValidationError's Rc + unsafe { + ::dafny_runtime::dafny_runtime_conversions::object::dafny_class_to_struct(typed) + } + ) + } else { + crate::types::error::Error::Opaque { + obj: obj.clone() + } + } + }, + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints.rs b/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints.rs new file mode 100644 index 000000000..c06fecfd2 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints.rs @@ -0,0 +1,6 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +pub mod _get_constraints_input; + + pub mod _get_constraints_output; diff --git a/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_input.rs b/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_input.rs new file mode 100644 index 000000000..70ac04aa9 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_input.rs @@ -0,0 +1,192 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[allow(dead_code)] +pub fn to_dafny( + value: crate::operation::get_constraints::GetConstraintsInput, +) -> ::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::GetConstraintsInput, +>{ + ::std::rc::Rc::new(crate::r#simple::constraints::internaldafny::types::GetConstraintsInput::GetConstraintsInput { + MyString: crate::standard_library_conversions::ostring_to_dafny(&value.my_string), + NonEmptyString: crate::standard_library_conversions::ostring_to_dafny(&value.non_empty_string), + StringLessThanOrEqualToTen: crate::standard_library_conversions::ostring_to_dafny(&value.string_less_than_or_equal_to_ten), + MyBlob: crate::standard_library_conversions::oblob_to_dafny(&value.my_blob), + NonEmptyBlob: crate::standard_library_conversions::oblob_to_dafny(&value.non_empty_blob), + BlobLessThanOrEqualToTen: crate::standard_library_conversions::oblob_to_dafny(&value.blob_less_than_or_equal_to_ten), + MyList: ::std::rc::Rc::new(match &value.my_list { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&e), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + NonEmptyList: ::std::rc::Rc::new(match &value.non_empty_list { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&e), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + ListLessThanOrEqualToTen: ::std::rc::Rc::new(match &value.list_less_than_or_equal_to_ten { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&e), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + MyMap: +::std::rc::Rc::new(match &value.my_map { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::hashmap_to_dafny_map(x, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&v), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + NonEmptyMap: +::std::rc::Rc::new(match &value.non_empty_map { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::hashmap_to_dafny_map(x, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&v), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + MapLessThanOrEqualToTen: +::std::rc::Rc::new(match &value.map_less_than_or_equal_to_ten { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::hashmap_to_dafny_map(x, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&v), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + OneToTen: crate::standard_library_conversions::oint_to_dafny(value.one_to_ten), + myTenToTen: crate::standard_library_conversions::olong_to_dafny(&value.my_ten_to_ten), + GreaterThanOne: crate::standard_library_conversions::oint_to_dafny(value.greater_than_one), + LessThanTen: crate::standard_library_conversions::oint_to_dafny(value.less_than_ten), + MyUtf8Bytes: (match value.my_utf8_bytes { + Some(s) => crate::_Wrappers_Compile::Option::Some { value: dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&s.as_bytes().to_vec(), |b| *b) }, + None => crate::_Wrappers_Compile::Option::None {}, +}).into(), + MyListOfUtf8Bytes: ::std::rc::Rc::new(match &value.my_list_of_utf8_bytes { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&e.as_bytes().to_vec(), |b| *b), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + }) +} + #[allow(dead_code)] +pub fn from_dafny( + dafny_value: ::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::GetConstraintsInput, + >, +) -> crate::operation::get_constraints::GetConstraintsInput { + crate::operation::get_constraints::GetConstraintsInput::builder() + .set_my_string(crate::standard_library_conversions::ostring_from_dafny(dafny_value.MyString().clone())) + .set_non_empty_string(crate::standard_library_conversions::ostring_from_dafny(dafny_value.NonEmptyString().clone())) + .set_string_less_than_or_equal_to_ten(crate::standard_library_conversions::ostring_from_dafny(dafny_value.StringLessThanOrEqualToTen().clone())) + .set_my_blob(crate::standard_library_conversions::oblob_from_dafny(dafny_value.MyBlob().clone())) + .set_non_empty_blob(crate::standard_library_conversions::oblob_from_dafny(dafny_value.NonEmptyBlob().clone())) + .set_blob_less_than_or_equal_to_ten(crate::standard_library_conversions::oblob_from_dafny(dafny_value.BlobLessThanOrEqualToTen().clone())) + .set_my_list(match (*dafny_value.MyList()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(e), + ) + ), + _ => None +} +) + .set_non_empty_list(match (*dafny_value.NonEmptyList()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(e), + ) + ), + _ => None +} +) + .set_list_less_than_or_equal_to_ten(match (*dafny_value.ListLessThanOrEqualToTen()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(e), + ) + ), + _ => None +} +) + .set_my_map(match (*dafny_value.MyMap()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_map_to_hashmap(value, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(v), + ) + ), + _ => None +} +) + .set_non_empty_map(match (*dafny_value.NonEmptyMap()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_map_to_hashmap(value, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(v), + ) + ), + _ => None +} +) + .set_map_less_than_or_equal_to_ten(match (*dafny_value.MapLessThanOrEqualToTen()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_map_to_hashmap(value, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(v), + ) + ), + _ => None +} +) + .set_one_to_ten(crate::standard_library_conversions::oint_from_dafny(dafny_value.OneToTen().clone())) + .set_my_ten_to_ten(crate::standard_library_conversions::olong_from_dafny(dafny_value.myTenToTen().clone())) + .set_greater_than_one(crate::standard_library_conversions::oint_from_dafny(dafny_value.GreaterThanOne().clone())) + .set_less_than_ten(crate::standard_library_conversions::oint_from_dafny(dafny_value.LessThanTen().clone())) + .set_my_utf8_bytes(match dafny_value.MyUtf8Bytes().as_ref() { + crate::_Wrappers_Compile::Option::Some { .. } => ::std::option::Option::Some(::std::string::String::from_utf8(dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(&dafny_value.MyUtf8Bytes().Extract(), |b| *b)).unwrap()), + _ => ::std::option::Option::None, +}) + .set_my_list_of_utf8_bytes(match (*dafny_value.MyListOfUtf8Bytes()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| ::std::string::String::from_utf8(dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(&::std::borrow::Borrow::borrow(e), |b| *b)).unwrap(), + ) + ), + _ => None +} +) + .build() + .unwrap() +} diff --git a/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_output.rs b/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_output.rs new file mode 100644 index 000000000..40dc94a3a --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions/get_constraints/_get_constraints_output.rs @@ -0,0 +1,192 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[allow(dead_code)] +pub fn to_dafny( + value: crate::operation::get_constraints::GetConstraintsOutput, +) -> ::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::GetConstraintsOutput, +>{ + ::std::rc::Rc::new(crate::r#simple::constraints::internaldafny::types::GetConstraintsOutput::GetConstraintsOutput { + MyString: crate::standard_library_conversions::ostring_to_dafny(&value.my_string), + NonEmptyString: crate::standard_library_conversions::ostring_to_dafny(&value.non_empty_string), + StringLessThanOrEqualToTen: crate::standard_library_conversions::ostring_to_dafny(&value.string_less_than_or_equal_to_ten), + MyBlob: crate::standard_library_conversions::oblob_to_dafny(&value.my_blob), + NonEmptyBlob: crate::standard_library_conversions::oblob_to_dafny(&value.non_empty_blob), + BlobLessThanOrEqualToTen: crate::standard_library_conversions::oblob_to_dafny(&value.blob_less_than_or_equal_to_ten), + MyList: ::std::rc::Rc::new(match &value.my_list { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&e), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + NonEmptyList: ::std::rc::Rc::new(match &value.non_empty_list { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&e), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + ListLessThanOrEqualToTen: ::std::rc::Rc::new(match &value.list_less_than_or_equal_to_ten { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&e), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + MyMap: +::std::rc::Rc::new(match &value.my_map { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::hashmap_to_dafny_map(x, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&v), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + NonEmptyMap: +::std::rc::Rc::new(match &value.non_empty_map { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::hashmap_to_dafny_map(x, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&v), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + MapLessThanOrEqualToTen: +::std::rc::Rc::new(match &value.map_less_than_or_equal_to_ten { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::hashmap_to_dafny_map(x, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&v), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + OneToTen: crate::standard_library_conversions::oint_to_dafny(value.one_to_ten), + thatTenToTen: crate::standard_library_conversions::olong_to_dafny(&value.that_ten_to_ten), + GreaterThanOne: crate::standard_library_conversions::oint_to_dafny(value.greater_than_one), + LessThanTen: crate::standard_library_conversions::oint_to_dafny(value.less_than_ten), + MyUtf8Bytes: (match value.my_utf8_bytes { + Some(s) => crate::_Wrappers_Compile::Option::Some { value: dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&s.as_bytes().to_vec(), |b| *b) }, + None => crate::_Wrappers_Compile::Option::None {}, +}).into(), + MyListOfUtf8Bytes: ::std::rc::Rc::new(match &value.my_list_of_utf8_bytes { + Some(x) => crate::r#_Wrappers_Compile::Option::Some { value : + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(x, + |e| dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&e.as_bytes().to_vec(), |b| *b), + ) + }, + None => crate::r#_Wrappers_Compile::Option::None {} +}) +, + }) +} + #[allow(dead_code)] +pub fn from_dafny( + dafny_value: ::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::GetConstraintsOutput, + >, +) -> crate::operation::get_constraints::GetConstraintsOutput { + crate::operation::get_constraints::GetConstraintsOutput::builder() + .set_my_string(crate::standard_library_conversions::ostring_from_dafny(dafny_value.MyString().clone())) + .set_non_empty_string(crate::standard_library_conversions::ostring_from_dafny(dafny_value.NonEmptyString().clone())) + .set_string_less_than_or_equal_to_ten(crate::standard_library_conversions::ostring_from_dafny(dafny_value.StringLessThanOrEqualToTen().clone())) + .set_my_blob(crate::standard_library_conversions::oblob_from_dafny(dafny_value.MyBlob().clone())) + .set_non_empty_blob(crate::standard_library_conversions::oblob_from_dafny(dafny_value.NonEmptyBlob().clone())) + .set_blob_less_than_or_equal_to_ten(crate::standard_library_conversions::oblob_from_dafny(dafny_value.BlobLessThanOrEqualToTen().clone())) + .set_my_list(match (*dafny_value.MyList()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(e), + ) + ), + _ => None +} +) + .set_non_empty_list(match (*dafny_value.NonEmptyList()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(e), + ) + ), + _ => None +} +) + .set_list_less_than_or_equal_to_ten(match (*dafny_value.ListLessThanOrEqualToTen()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(e), + ) + ), + _ => None +} +) + .set_my_map(match (*dafny_value.MyMap()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_map_to_hashmap(value, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(v), + ) + ), + _ => None +} +) + .set_non_empty_map(match (*dafny_value.NonEmptyMap()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_map_to_hashmap(value, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(v), + ) + ), + _ => None +} +) + .set_map_less_than_or_equal_to_ten(match (*dafny_value.MapLessThanOrEqualToTen()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_map_to_hashmap(value, + |k| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(k), + |v| dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string(v), + ) + ), + _ => None +} +) + .set_one_to_ten(crate::standard_library_conversions::oint_from_dafny(dafny_value.OneToTen().clone())) + .set_that_ten_to_ten(crate::standard_library_conversions::olong_from_dafny(dafny_value.thatTenToTen().clone())) + .set_greater_than_one(crate::standard_library_conversions::oint_from_dafny(dafny_value.GreaterThanOne().clone())) + .set_less_than_ten(crate::standard_library_conversions::oint_from_dafny(dafny_value.LessThanTen().clone())) + .set_my_utf8_bytes(match dafny_value.MyUtf8Bytes().as_ref() { + crate::_Wrappers_Compile::Option::Some { .. } => ::std::option::Option::Some(::std::string::String::from_utf8(dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(&dafny_value.MyUtf8Bytes().Extract(), |b| *b)).unwrap()), + _ => ::std::option::Option::None, +}) + .set_my_list_of_utf8_bytes(match (*dafny_value.MyListOfUtf8Bytes()).as_ref() { + crate::r#_Wrappers_Compile::Option::Some { value } => + Some( + ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(value, + |e| ::std::string::String::from_utf8(dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(&::std::borrow::Borrow::borrow(e), |b| *b)).unwrap(), + ) + ), + _ => None +} +) + .build() + .unwrap() +} diff --git a/TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config.rs b/TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config.rs new file mode 100644 index 000000000..7c9daf5e5 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config.rs @@ -0,0 +1,4 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +pub mod _simple_constraints_config; diff --git a/TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config/_simple_constraints_config.rs b/TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config/_simple_constraints_config.rs new file mode 100644 index 000000000..a9122b8e1 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/conversions/simple_constraints_config/_simple_constraints_config.rs @@ -0,0 +1,44 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[allow(dead_code)] + +pub fn to_dafny( + value: crate::types::simple_constraints_config::SimpleConstraintsConfig, +) -> ::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig, +> { + ::std::rc::Rc::new(to_dafny_plain(value)) +} + +#[allow(dead_code)] +pub fn from_dafny( + dafny_value: ::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig, + >, +) -> crate::types::simple_constraints_config::SimpleConstraintsConfig { + plain_from_dafny(&*dafny_value) +} + + +#[allow(dead_code)] +pub fn to_dafny_plain( + value: crate::types::simple_constraints_config::SimpleConstraintsConfig, +) -> crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig { + crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig::SimpleConstraintsConfig { + + } +} + +#[allow(dead_code)] +pub fn plain_from_dafny( + dafny_value: &crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig, +) -> crate::types::simple_constraints_config::SimpleConstraintsConfig { + match dafny_value { + crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig::SimpleConstraintsConfig {..} => + crate::types::simple_constraints_config::SimpleConstraintsConfig::builder() + + .build() + .unwrap() + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/error.rs b/TestModels/Constraints/runtimes/rust/src/error.rs new file mode 100644 index 000000000..4cddaa7c3 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/error.rs @@ -0,0 +1,16 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +pub use ::aws_smithy_runtime_api::box_error::BoxError; + +/// Error type returned by the client. +pub type SdkError = + ::aws_smithy_runtime_api::client::result::SdkError; +pub use ::aws_smithy_runtime_api::client::result::ConnectorError; +pub use ::aws_smithy_types::error::operation::BuildError; + +pub use ::aws_smithy_types::error::display::DisplayErrorContext; +pub use ::aws_smithy_types::error::metadata::ErrorMetadata; +pub use ::aws_smithy_types::error::metadata::ProvideErrorMetadata; + +pub(crate) mod sealed_unhandled; diff --git a/TestModels/Constraints/runtimes/rust/src/error/sealed_unhandled.rs b/TestModels/Constraints/runtimes/rust/src/error/sealed_unhandled.rs new file mode 100644 index 000000000..eae800729 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/error/sealed_unhandled.rs @@ -0,0 +1,32 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +use std::any::Any; + +use dafny_runtime::UpcastObject; + +/// This struct is not intended to be used. +/// +/// This struct holds information about an unhandled error, +/// but that information should be obtained by using the +/// [`ProvideErrorMetadata`](::aws_smithy_types::error::metadata::ProvideErrorMetadata) trait +/// on the error type. +/// +/// This struct intentionally doesn't yield any useful information itself. +#[deprecated( + note = "Matching `Unhandled` directly is not forwards compatible. Instead, match using a \ +variable wildcard pattern and check `.code()`: + \ +   `err if err.code() == Some(\"SpecificExceptionCode\") => { /* handle the error */ }` + \ +See [`ProvideErrorMetadata`](::aws_smithy_types::error::metadata::ProvideErrorMetadata) for what information is available for the error." +)] +#[derive(Debug)] +pub struct Unhandled { + pub(crate) source: ::aws_smithy_runtime_api::box_error::BoxError, + pub(crate) meta: ::aws_smithy_types::error::metadata::ErrorMetadata, +} + +impl UpcastObject for Unhandled { + ::dafny_runtime::UpcastObjectFn!(dyn ::std::any::Any); +} diff --git a/TestModels/Constraints/runtimes/rust/src/operation.rs b/TestModels/Constraints/runtimes/rust/src/operation.rs new file mode 100644 index 000000000..a0d185ab4 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/operation.rs @@ -0,0 +1,5 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +/// Types for the `GetConstraints` operation. +pub mod get_constraints; diff --git a/TestModels/Constraints/runtimes/rust/src/operation/get_constraints.rs b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints.rs new file mode 100644 index 000000000..67d7d725f --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints.rs @@ -0,0 +1,156 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +/// Orchestration and serialization glue logic for `GetConstraints`. +#[derive(::std::clone::Clone, ::std::default::Default, ::std::fmt::Debug)] +#[non_exhaustive] +pub struct GetConstraints; +impl GetConstraints { + /// Creates a new `GetConstraints` + pub fn new() -> Self { + Self + } + + pub(crate) async fn send( + client: &crate::client::Client, + input: crate::operation::get_constraints::GetConstraintsInput, + ) -> ::std::result::Result< + crate::operation::get_constraints::GetConstraintsOutput, + crate::types::error::Error, + > { + if matches!(input.my_string, Some(ref x) if !(1..=10).contains(&x.chars().map(::std::primitive::char::len_utf16).fold(0usize, ::std::ops::Add::add))) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "my_string", + "my_string failed to satisfy constraint: Member must have length between 1 and 10, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.non_empty_string, Some(ref x) if !(1..).contains(&x.chars().map(::std::primitive::char::len_utf16).fold(0usize, ::std::ops::Add::add))) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "non_empty_string", + "non_empty_string failed to satisfy constraint: Member must have length greater than or equal to 1", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.string_less_than_or_equal_to_ten, Some(ref x) if !(..=10).contains(&x.chars().map(::std::primitive::char::len_utf16).fold(0usize, ::std::ops::Add::add))) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "string_less_than_or_equal_to_ten", + "string_less_than_or_equal_to_ten failed to satisfy constraint: Member must have length less than or equal to 10", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.my_blob, Some(ref x) if !(1..=10).contains(&x.as_ref().len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "my_blob", + "my_blob failed to satisfy constraint: Member must have length between 1 and 10, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.non_empty_blob, Some(ref x) if !(1..).contains(&x.as_ref().len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "non_empty_blob", + "non_empty_blob failed to satisfy constraint: Member must have length greater than or equal to 1", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.blob_less_than_or_equal_to_ten, Some(ref x) if !(..=10).contains(&x.as_ref().len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "blob_less_than_or_equal_to_ten", + "blob_less_than_or_equal_to_ten failed to satisfy constraint: Member must have length less than or equal to 10", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.my_list, Some(ref x) if !(1..=10).contains(&x.len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "my_list", + "my_list failed to satisfy constraint: Member must have length between 1 and 10, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.non_empty_list, Some(ref x) if !(1..).contains(&x.len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "non_empty_list", + "non_empty_list failed to satisfy constraint: Member must have length greater than or equal to 1", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.list_less_than_or_equal_to_ten, Some(ref x) if !(..=10).contains(&x.len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "list_less_than_or_equal_to_ten", + "list_less_than_or_equal_to_ten failed to satisfy constraint: Member must have length less than or equal to 10", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.my_map, Some(ref x) if !(1..=10).contains(&x.len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "my_map", + "my_map failed to satisfy constraint: Member must have length between 1 and 10, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.non_empty_map, Some(ref x) if !(1..).contains(&x.len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "non_empty_map", + "non_empty_map failed to satisfy constraint: Member must have length greater than or equal to 1", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.map_less_than_or_equal_to_ten, Some(ref x) if !(..=10).contains(&x.len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "map_less_than_or_equal_to_ten", + "map_less_than_or_equal_to_ten failed to satisfy constraint: Member must have length less than or equal to 10", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.one_to_ten, Some(x) if !(1..=10).contains(&x)) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "one_to_ten", + "one_to_ten failed to satisfy constraint: Member must be between 1 and 10, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.my_ten_to_ten, Some(x) if !(-10..=10).contains(&x)) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "my_ten_to_ten", + "my_ten_to_ten failed to satisfy constraint: Member must be between -10 and 10, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.greater_than_one, Some(x) if !(1..).contains(&x)) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "greater_than_one", + "greater_than_one failed to satisfy constraint: Member must be greater than or equal to 1", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.less_than_ten, Some(x) if !(..=10).contains(&x)) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "less_than_ten", + "less_than_ten failed to satisfy constraint: Member must be less than or equal to 10", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.my_utf8_bytes, Some(ref x) if !(1..=10).contains(&x.chars().count())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "my_utf8_bytes", + "my_utf8_bytes failed to satisfy constraint: Member must have length between 1 and 10, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} +if matches!(input.my_list_of_utf8_bytes, Some(ref x) if !(1..=2).contains(&x.len())) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "my_list_of_utf8_bytes", + "my_list_of_utf8_bytes failed to satisfy constraint: Member must have length between 1 and 2, inclusive", + )).map_err(crate::types::error::Error::wrap_validation_err); +} + let inner_input = crate::conversions::get_constraints::_get_constraints_input::to_dafny(input); + let inner_result = + ::dafny_runtime::md!(client.dafny_client.clone()).GetConstraints(&inner_input); + if matches!( + inner_result.as_ref(), + crate::r#_Wrappers_Compile::Result::Success { .. } + ) { + Ok( + crate::conversions::get_constraints::_get_constraints_output::from_dafny(inner_result.value().clone()), + ) + } else { + Err(crate::conversions::error::from_dafny( + inner_result.error().clone(), + )) + } + } +} + +pub use crate::operation::get_constraints::_get_constraints_output::GetConstraintsOutput; + +pub use crate::operation::get_constraints::_get_constraints_input::GetConstraintsInput; + +pub(crate) mod _get_constraints_output; + +pub(crate) mod _get_constraints_input; + +/// Builders +pub mod builders; diff --git a/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_input.rs b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_input.rs new file mode 100644 index 000000000..8f78f7408 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_input.rs @@ -0,0 +1,432 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[allow(missing_docs)] // documentation missing in model +#[non_exhaustive] +#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)] +pub struct GetConstraintsInput { + #[allow(missing_docs)] // documentation missing in model +pub blob_less_than_or_equal_to_ten: ::std::option::Option<::aws_smithy_types::Blob>, +#[allow(missing_docs)] // documentation missing in model +pub greater_than_one: ::std::option::Option<::std::primitive::i32>, +#[allow(missing_docs)] // documentation missing in model +pub less_than_ten: ::std::option::Option<::std::primitive::i32>, +#[allow(missing_docs)] // documentation missing in model +pub list_less_than_or_equal_to_ten: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub map_less_than_or_equal_to_ten: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_blob: ::std::option::Option<::aws_smithy_types::Blob>, +#[allow(missing_docs)] // documentation missing in model +pub my_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_list_of_utf8_bytes: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_string: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub my_utf8_bytes: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_blob: ::std::option::Option<::aws_smithy_types::Blob>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_string: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub one_to_ten: ::std::option::Option<::std::primitive::i32>, +#[allow(missing_docs)] // documentation missing in model +pub string_less_than_or_equal_to_ten: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub my_ten_to_ten: ::std::option::Option<::std::primitive::i64>, +} +impl GetConstraintsInput { + #[allow(missing_docs)] // documentation missing in model +pub fn blob_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.blob_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn greater_than_one(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.greater_than_one +} +#[allow(missing_docs)] // documentation missing in model +pub fn less_than_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.less_than_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn list_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.list_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn map_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.map_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.my_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list_of_utf8_bytes(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list_of_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.my_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_string(&self) -> &::std::option::Option<::std::string::String> { + &self.my_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_utf8_bytes(&self) -> &::std::option::Option<::std::string::String> { + &self.my_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.non_empty_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.non_empty_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.non_empty_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_string(&self) -> &::std::option::Option<::std::string::String> { + &self.non_empty_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn one_to_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.one_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn string_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::string::String> { + &self.string_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_ten_to_ten(&self) -> &::std::option::Option<::std::primitive::i64> { + &self.my_ten_to_ten +} +} +impl GetConstraintsInput { + /// Creates a new builder-style object to manufacture [`GetConstraintsInput`](crate::operation::get_constraints::builders::GetConstraintsInput). + pub fn builder() -> crate::operation::get_constraints::builders::GetConstraintsInputBuilder { + crate::operation::get_constraints::builders::GetConstraintsInputBuilder::default() + } +} + +/// A builder for [`GetConstraintsInput`](crate::operation::operation::GetConstraintsInput). +#[non_exhaustive] +#[derive( + ::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug, +)] +pub struct GetConstraintsInputBuilder { + pub(crate) blob_less_than_or_equal_to_ten: ::std::option::Option<::aws_smithy_types::Blob>, +pub(crate) greater_than_one: ::std::option::Option<::std::primitive::i32>, +pub(crate) less_than_ten: ::std::option::Option<::std::primitive::i32>, +pub(crate) list_less_than_or_equal_to_ten: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) map_less_than_or_equal_to_ten: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +pub(crate) my_blob: ::std::option::Option<::aws_smithy_types::Blob>, +pub(crate) my_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) my_list_of_utf8_bytes: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) my_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +pub(crate) my_string: ::std::option::Option<::std::string::String>, +pub(crate) my_utf8_bytes: ::std::option::Option<::std::string::String>, +pub(crate) non_empty_blob: ::std::option::Option<::aws_smithy_types::Blob>, +pub(crate) non_empty_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) non_empty_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +pub(crate) non_empty_string: ::std::option::Option<::std::string::String>, +pub(crate) one_to_ten: ::std::option::Option<::std::primitive::i32>, +pub(crate) string_less_than_or_equal_to_ten: ::std::option::Option<::std::string::String>, +pub(crate) my_ten_to_ten: ::std::option::Option<::std::primitive::i64>, +} +impl GetConstraintsInputBuilder { + #[allow(missing_docs)] // documentation missing in model +pub fn blob_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.blob_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_blob_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.blob_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_blob_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.blob_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn greater_than_one(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.greater_than_one = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_greater_than_one(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.greater_than_one = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_greater_than_one(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.greater_than_one +} +#[allow(missing_docs)] // documentation missing in model +pub fn less_than_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.less_than_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_less_than_ten(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.less_than_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_less_than_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.less_than_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn list_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.list_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_list_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.list_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_list_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.list_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn map_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.map_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_map_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.map_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_map_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.map_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_blob(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.my_blob = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_blob(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.my_blob = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.my_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_list(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list_of_utf8_bytes(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list_of_utf8_bytes = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_list_of_utf8_bytes(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list_of_utf8_bytes = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_list_of_utf8_bytes(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list_of_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_map(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.my_map = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_map(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.my_map = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.my_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_string(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.my_string = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_string(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.my_string = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_string(&self) -> &::std::option::Option<::std::string::String> { + &self.my_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_utf8_bytes(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.my_utf8_bytes = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_utf8_bytes(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.my_utf8_bytes = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_utf8_bytes(&self) -> &::std::option::Option<::std::string::String> { + &self.my_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_blob(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.non_empty_blob = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_blob(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.non_empty_blob = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.non_empty_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_list(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.non_empty_list = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_list(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.non_empty_list = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.non_empty_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_map(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.non_empty_map = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_map(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.non_empty_map = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.non_empty_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_string(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.non_empty_string = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_string(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.non_empty_string = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_string(&self) -> &::std::option::Option<::std::string::String> { + &self.non_empty_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn one_to_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.one_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_one_to_ten(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.one_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_one_to_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.one_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn string_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.string_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_string_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.string_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_string_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::string::String> { + &self.string_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_ten_to_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i64>) -> Self { + self.my_ten_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_ten_to_ten(mut self, input: ::std::option::Option<::std::primitive::i64>) -> Self { + self.my_ten_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_ten_to_ten(&self) -> &::std::option::Option<::std::primitive::i64> { + &self.my_ten_to_ten +} + /// Consumes the builder and constructs a [`GetConstraintsInput`](crate::operation::operation::GetConstraintsInput). + pub fn build( + self, + ) -> ::std::result::Result< + crate::operation::get_constraints::GetConstraintsInput, + ::aws_smithy_types::error::operation::BuildError, + > { + ::std::result::Result::Ok(crate::operation::get_constraints::GetConstraintsInput { + blob_less_than_or_equal_to_ten: self.blob_less_than_or_equal_to_ten, +greater_than_one: self.greater_than_one, +less_than_ten: self.less_than_ten, +list_less_than_or_equal_to_ten: self.list_less_than_or_equal_to_ten, +map_less_than_or_equal_to_ten: self.map_less_than_or_equal_to_ten, +my_blob: self.my_blob, +my_list: self.my_list, +my_list_of_utf8_bytes: self.my_list_of_utf8_bytes, +my_map: self.my_map, +my_string: self.my_string, +my_utf8_bytes: self.my_utf8_bytes, +non_empty_blob: self.non_empty_blob, +non_empty_list: self.non_empty_list, +non_empty_map: self.non_empty_map, +non_empty_string: self.non_empty_string, +one_to_ten: self.one_to_ten, +string_less_than_or_equal_to_ten: self.string_less_than_or_equal_to_ten, +my_ten_to_ten: self.my_ten_to_ten, + }) + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_output.rs b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_output.rs new file mode 100644 index 000000000..1edc3e2d0 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/_get_constraints_output.rs @@ -0,0 +1,432 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[allow(missing_docs)] // documentation missing in model +#[non_exhaustive] +#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)] +pub struct GetConstraintsOutput { + #[allow(missing_docs)] // documentation missing in model +pub blob_less_than_or_equal_to_ten: ::std::option::Option<::aws_smithy_types::Blob>, +#[allow(missing_docs)] // documentation missing in model +pub greater_than_one: ::std::option::Option<::std::primitive::i32>, +#[allow(missing_docs)] // documentation missing in model +pub less_than_ten: ::std::option::Option<::std::primitive::i32>, +#[allow(missing_docs)] // documentation missing in model +pub list_less_than_or_equal_to_ten: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub map_less_than_or_equal_to_ten: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_blob: ::std::option::Option<::aws_smithy_types::Blob>, +#[allow(missing_docs)] // documentation missing in model +pub my_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_list_of_utf8_bytes: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub my_string: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub my_utf8_bytes: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_blob: ::std::option::Option<::aws_smithy_types::Blob>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +#[allow(missing_docs)] // documentation missing in model +pub non_empty_string: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub one_to_ten: ::std::option::Option<::std::primitive::i32>, +#[allow(missing_docs)] // documentation missing in model +pub string_less_than_or_equal_to_ten: ::std::option::Option<::std::string::String>, +#[allow(missing_docs)] // documentation missing in model +pub that_ten_to_ten: ::std::option::Option<::std::primitive::i64>, +} +impl GetConstraintsOutput { + #[allow(missing_docs)] // documentation missing in model +pub fn blob_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.blob_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn greater_than_one(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.greater_than_one +} +#[allow(missing_docs)] // documentation missing in model +pub fn less_than_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.less_than_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn list_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.list_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn map_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.map_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.my_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list_of_utf8_bytes(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list_of_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.my_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_string(&self) -> &::std::option::Option<::std::string::String> { + &self.my_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_utf8_bytes(&self) -> &::std::option::Option<::std::string::String> { + &self.my_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.non_empty_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.non_empty_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.non_empty_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_string(&self) -> &::std::option::Option<::std::string::String> { + &self.non_empty_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn one_to_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.one_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn string_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::string::String> { + &self.string_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn that_ten_to_ten(&self) -> &::std::option::Option<::std::primitive::i64> { + &self.that_ten_to_ten +} +} +impl GetConstraintsOutput { + /// Creates a new builder-style object to manufacture [`GetConstraintsOutput`](crate::operation::get_constraints::builders::GetConstraintsOutput). + pub fn builder() -> crate::operation::get_constraints::builders::GetConstraintsOutputBuilder { + crate::operation::get_constraints::builders::GetConstraintsOutputBuilder::default() + } +} + +/// A builder for [`GetConstraintsOutput`](crate::operation::operation::GetConstraintsOutput). +#[non_exhaustive] +#[derive( + ::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug, +)] +pub struct GetConstraintsOutputBuilder { + pub(crate) blob_less_than_or_equal_to_ten: ::std::option::Option<::aws_smithy_types::Blob>, +pub(crate) greater_than_one: ::std::option::Option<::std::primitive::i32>, +pub(crate) less_than_ten: ::std::option::Option<::std::primitive::i32>, +pub(crate) list_less_than_or_equal_to_ten: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) map_less_than_or_equal_to_ten: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +pub(crate) my_blob: ::std::option::Option<::aws_smithy_types::Blob>, +pub(crate) my_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) my_list_of_utf8_bytes: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) my_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +pub(crate) my_string: ::std::option::Option<::std::string::String>, +pub(crate) my_utf8_bytes: ::std::option::Option<::std::string::String>, +pub(crate) non_empty_blob: ::std::option::Option<::aws_smithy_types::Blob>, +pub(crate) non_empty_list: ::std::option::Option<::std::vec::Vec<::std::string::String>>, +pub(crate) non_empty_map: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>, +pub(crate) non_empty_string: ::std::option::Option<::std::string::String>, +pub(crate) one_to_ten: ::std::option::Option<::std::primitive::i32>, +pub(crate) string_less_than_or_equal_to_ten: ::std::option::Option<::std::string::String>, +pub(crate) that_ten_to_ten: ::std::option::Option<::std::primitive::i64>, +} +impl GetConstraintsOutputBuilder { + #[allow(missing_docs)] // documentation missing in model +pub fn blob_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.blob_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_blob_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.blob_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_blob_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.blob_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn greater_than_one(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.greater_than_one = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_greater_than_one(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.greater_than_one = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_greater_than_one(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.greater_than_one +} +#[allow(missing_docs)] // documentation missing in model +pub fn less_than_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.less_than_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_less_than_ten(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.less_than_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_less_than_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.less_than_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn list_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.list_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_list_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.list_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_list_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.list_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn map_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.map_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_map_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.map_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_map_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.map_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_blob(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.my_blob = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_blob(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.my_blob = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.my_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_list(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list_of_utf8_bytes(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list_of_utf8_bytes = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_list_of_utf8_bytes(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.my_list_of_utf8_bytes = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_list_of_utf8_bytes(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.my_list_of_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_map(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.my_map = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_map(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.my_map = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.my_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_string(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.my_string = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_string(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.my_string = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_string(&self) -> &::std::option::Option<::std::string::String> { + &self.my_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_utf8_bytes(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.my_utf8_bytes = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_utf8_bytes(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.my_utf8_bytes = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_utf8_bytes(&self) -> &::std::option::Option<::std::string::String> { + &self.my_utf8_bytes +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_blob(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.non_empty_blob = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_blob(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.non_empty_blob = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + &self.non_empty_blob +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_list(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.non_empty_list = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_list(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.non_empty_list = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + &self.non_empty_list +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_map(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.non_empty_map = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_map(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.non_empty_map = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + &self.non_empty_map +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_string(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.non_empty_string = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_string(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.non_empty_string = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_string(&self) -> &::std::option::Option<::std::string::String> { + &self.non_empty_string +} +#[allow(missing_docs)] // documentation missing in model +pub fn one_to_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.one_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_one_to_ten(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.one_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_one_to_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + &self.one_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn string_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.string_less_than_or_equal_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_string_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.string_less_than_or_equal_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_string_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::string::String> { + &self.string_less_than_or_equal_to_ten +} +#[allow(missing_docs)] // documentation missing in model +pub fn that_ten_to_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i64>) -> Self { + self.that_ten_to_ten = ::std::option::Option::Some(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_that_ten_to_ten(mut self, input: ::std::option::Option<::std::primitive::i64>) -> Self { + self.that_ten_to_ten = input; + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_that_ten_to_ten(&self) -> &::std::option::Option<::std::primitive::i64> { + &self.that_ten_to_ten +} + /// Consumes the builder and constructs a [`GetConstraintsOutput`](crate::operation::operation::GetConstraintsOutput). + pub fn build( + self, + ) -> ::std::result::Result< + crate::operation::get_constraints::GetConstraintsOutput, + ::aws_smithy_types::error::operation::BuildError, + > { + ::std::result::Result::Ok(crate::operation::get_constraints::GetConstraintsOutput { + blob_less_than_or_equal_to_ten: self.blob_less_than_or_equal_to_ten, +greater_than_one: self.greater_than_one, +less_than_ten: self.less_than_ten, +list_less_than_or_equal_to_ten: self.list_less_than_or_equal_to_ten, +map_less_than_or_equal_to_ten: self.map_less_than_or_equal_to_ten, +my_blob: self.my_blob, +my_list: self.my_list, +my_list_of_utf8_bytes: self.my_list_of_utf8_bytes, +my_map: self.my_map, +my_string: self.my_string, +my_utf8_bytes: self.my_utf8_bytes, +non_empty_blob: self.non_empty_blob, +non_empty_list: self.non_empty_list, +non_empty_map: self.non_empty_map, +non_empty_string: self.non_empty_string, +one_to_ten: self.one_to_ten, +string_less_than_or_equal_to_ten: self.string_less_than_or_equal_to_ten, +that_ten_to_ten: self.that_ten_to_ten, + }) + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/builders.rs b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/builders.rs new file mode 100644 index 000000000..091ada9ce --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/operation/get_constraints/builders.rs @@ -0,0 +1,313 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +pub use crate::operation::get_constraints::_get_constraints_output::GetConstraintsOutputBuilder; + +pub use crate::operation::get_constraints::_get_constraints_input::GetConstraintsInputBuilder; + +impl GetConstraintsInputBuilder { + /// Sends a request with this input using the given client. + pub async fn send_with( + self, + client: &crate::client::Client, + ) -> ::std::result::Result< + crate::operation::get_constraints::GetConstraintsOutput, + crate::types::error::Error, + > { + let mut fluent_builder = client.get_constraints(); + fluent_builder.inner = self; + fluent_builder.send().await + } +} +/// Fluent builder constructing a request to `GetConstraints`. +/// +#[derive(::std::clone::Clone, ::std::fmt::Debug)] +pub struct GetConstraintsFluentBuilder { + client: crate::client::Client, + pub(crate) inner: crate::operation::get_constraints::builders::GetConstraintsInputBuilder, +} +impl GetConstraintsFluentBuilder { + /// Creates a new `GetConstraints`. + pub(crate) fn new(client: crate::client::Client) -> Self { + Self { + client, + inner: ::std::default::Default::default(), + } + } + /// Access the GetConstraints as a reference. + pub fn as_input(&self) -> &crate::operation::get_constraints::builders::GetConstraintsInputBuilder { + &self.inner + } + /// Sends the request and returns the response. + pub async fn send( + self, + ) -> ::std::result::Result< + crate::operation::get_constraints::GetConstraintsOutput, + crate::types::error::Error, + > { + let input = self + .inner + .build() + // Using Opaque since we don't have a validation-specific error yet. + // Operations' models don't declare their own validation error, + // and smithy-rs seems to not generate a ValidationError case unless there is. + // Vanilla smithy-rs uses SdkError::construction_failure, but we aren't using SdkError. + .map_err(|mut e| crate::types::error::Error::Opaque { + obj: ::dafny_runtime::Object::from_ref(&mut e as &mut dyn ::std::any::Any) + })?; + crate::operation::get_constraints::GetConstraints::send(&self.client, input).await + } + + #[allow(missing_docs)] // documentation missing in model +pub fn blob_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.inner = self.inner.blob_less_than_or_equal_to_ten(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_blob_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.inner = self.inner.set_blob_less_than_or_equal_to_ten(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_blob_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + self.inner.get_blob_less_than_or_equal_to_ten() +} +#[allow(missing_docs)] // documentation missing in model +pub fn greater_than_one(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.inner = self.inner.greater_than_one(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_greater_than_one(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.inner = self.inner.set_greater_than_one(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_greater_than_one(&self) -> &::std::option::Option<::std::primitive::i32> { + self.inner.get_greater_than_one() +} +#[allow(missing_docs)] // documentation missing in model +pub fn less_than_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.inner = self.inner.less_than_ten(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_less_than_ten(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.inner = self.inner.set_less_than_ten(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_less_than_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + self.inner.get_less_than_ten() +} +#[allow(missing_docs)] // documentation missing in model +pub fn list_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.list_less_than_or_equal_to_ten(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_list_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.set_list_less_than_or_equal_to_ten(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_list_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + self.inner.get_list_less_than_or_equal_to_ten() +} +#[allow(missing_docs)] // documentation missing in model +pub fn map_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.inner = self.inner.map_less_than_or_equal_to_ten(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_map_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.inner = self.inner.set_map_less_than_or_equal_to_ten(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_map_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + self.inner.get_map_less_than_or_equal_to_ten() +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_blob(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.inner = self.inner.my_blob(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_blob(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.inner = self.inner.set_my_blob(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + self.inner.get_my_blob() +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.my_list(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_list(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.set_my_list(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + self.inner.get_my_list() +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_list_of_utf8_bytes(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.my_list_of_utf8_bytes(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_list_of_utf8_bytes(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.set_my_list_of_utf8_bytes(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_list_of_utf8_bytes(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + self.inner.get_my_list_of_utf8_bytes() +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_map(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.inner = self.inner.my_map(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_map(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.inner = self.inner.set_my_map(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + self.inner.get_my_map() +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_string(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.inner = self.inner.my_string(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_string(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.inner = self.inner.set_my_string(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_string(&self) -> &::std::option::Option<::std::string::String> { + self.inner.get_my_string() +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_utf8_bytes(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.inner = self.inner.my_utf8_bytes(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_utf8_bytes(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.inner = self.inner.set_my_utf8_bytes(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_utf8_bytes(&self) -> &::std::option::Option<::std::string::String> { + self.inner.get_my_utf8_bytes() +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_blob(mut self, input: impl ::std::convert::Into<::aws_smithy_types::Blob>) -> Self { + self.inner = self.inner.non_empty_blob(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_blob(mut self, input: ::std::option::Option<::aws_smithy_types::Blob>) -> Self { + self.inner = self.inner.set_non_empty_blob(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_blob(&self) -> &::std::option::Option<::aws_smithy_types::Blob> { + self.inner.get_non_empty_blob() +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_list(mut self, input: impl ::std::convert::Into<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.non_empty_list(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_list(mut self, input: ::std::option::Option<::std::vec::Vec<::std::string::String>>) -> Self { + self.inner = self.inner.set_non_empty_list(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_list(&self) -> &::std::option::Option<::std::vec::Vec<::std::string::String>> { + self.inner.get_non_empty_list() +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_map(mut self, input: impl ::std::convert::Into<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.inner = self.inner.non_empty_map(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_map(mut self, input: ::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>>) -> Self { + self.inner = self.inner.set_non_empty_map(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_map(&self) -> &::std::option::Option<::std::collections::HashMap<::std::string::String, ::std::string::String>> { + self.inner.get_non_empty_map() +} +#[allow(missing_docs)] // documentation missing in model +pub fn non_empty_string(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.inner = self.inner.non_empty_string(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_non_empty_string(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.inner = self.inner.set_non_empty_string(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_non_empty_string(&self) -> &::std::option::Option<::std::string::String> { + self.inner.get_non_empty_string() +} +#[allow(missing_docs)] // documentation missing in model +pub fn one_to_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i32>) -> Self { + self.inner = self.inner.one_to_ten(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_one_to_ten(mut self, input: ::std::option::Option<::std::primitive::i32>) -> Self { + self.inner = self.inner.set_one_to_ten(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_one_to_ten(&self) -> &::std::option::Option<::std::primitive::i32> { + self.inner.get_one_to_ten() +} +#[allow(missing_docs)] // documentation missing in model +pub fn string_less_than_or_equal_to_ten(mut self, input: impl ::std::convert::Into<::std::string::String>) -> Self { + self.inner = self.inner.string_less_than_or_equal_to_ten(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_string_less_than_or_equal_to_ten(mut self, input: ::std::option::Option<::std::string::String>) -> Self { + self.inner = self.inner.set_string_less_than_or_equal_to_ten(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_string_less_than_or_equal_to_ten(&self) -> &::std::option::Option<::std::string::String> { + self.inner.get_string_less_than_or_equal_to_ten() +} +#[allow(missing_docs)] // documentation missing in model +pub fn my_ten_to_ten(mut self, input: impl ::std::convert::Into<::std::primitive::i64>) -> Self { + self.inner = self.inner.my_ten_to_ten(input.into()); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn set_my_ten_to_ten(mut self, input: ::std::option::Option<::std::primitive::i64>) -> Self { + self.inner = self.inner.set_my_ten_to_ten(input); + self +} +#[allow(missing_docs)] // documentation missing in model +pub fn get_my_ten_to_ten(&self) -> &::std::option::Option<::std::primitive::i64> { + self.inner.get_my_ten_to_ten() +} +} diff --git a/TestModels/Constraints/runtimes/rust/src/standard_library_conversions.rs b/TestModels/Constraints/runtimes/rust/src/standard_library_conversions.rs new file mode 100644 index 000000000..6bf8297d8 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/standard_library_conversions.rs @@ -0,0 +1,266 @@ +pub fn ostring_to_dafny( + input: &Option, +) -> ::std::rc::Rc< + crate::_Wrappers_Compile::Option<::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>>, +> { + let dafny_value = match input { + Some(b) => crate::_Wrappers_Compile::Option::Some { value: + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&b) + }, + None => crate::_Wrappers_Compile::Option::None {}, +}; + ::std::rc::Rc::new(dafny_value) +} + +pub fn ostring_from_dafny( + input: ::std::rc::Rc< + crate::_Wrappers_Compile::Option< + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + >, +) -> Option { + if matches!( + input.as_ref(), + crate::_Wrappers_Compile::Option::Some { .. } + ) { + Some( + dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + &input.Extract(), + ), + ) + } else { + None + } +} + +pub fn obool_to_dafny( + input: &Option, +) -> ::std::rc::Rc> { + let dafny_value = match input { + Some(b) => crate::_Wrappers_Compile::Option::Some { value: *b }, + None => crate::_Wrappers_Compile::Option::None {}, + }; + ::std::rc::Rc::new(dafny_value) +} + +pub fn obool_from_dafny( + input: ::std::rc::Rc>, +) -> Option { + if matches!( + input.as_ref(), + crate::_Wrappers_Compile::Option::Some { .. } + ) { + Some(input.Extract()) + } else { + None + } +} + +pub fn oint_to_dafny(input: Option) -> ::std::rc::Rc> { + let dafny_value = match input { + Some(b) => crate::_Wrappers_Compile::Option::Some { value: b }, + None => crate::_Wrappers_Compile::Option::None {}, + }; + ::std::rc::Rc::new(dafny_value) +} + +pub fn oint_from_dafny(input: ::std::rc::Rc>) -> Option { + if matches!( + input.as_ref(), + crate::_Wrappers_Compile::Option::Some { .. } + ) { + Some(input.Extract()) + } else { + None + } +} + +pub fn olong_to_dafny(input: &Option) -> ::std::rc::Rc> { + let dafny_value = match input { + Some(b) => crate::_Wrappers_Compile::Option::Some { value: *b }, + None => crate::_Wrappers_Compile::Option::None {}, + }; + ::std::rc::Rc::new(dafny_value) +} + +pub fn olong_from_dafny( + input: ::std::rc::Rc>, +) -> Option { + if matches!( + input.as_ref(), + crate::_Wrappers_Compile::Option::Some { .. } + ) { + Some(input.Extract()) + } else { + None + } +} + +pub fn blob_to_dafny(input: &::aws_smithy_types::Blob) -> ::dafny_runtime::Sequence { + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&input.clone().into_inner(), |x| *x) +} + +pub fn oblob_to_dafny( + input: &Option<::aws_smithy_types::Blob>, +) -> ::std::rc::Rc>> { + let dafny_value = match input { + Some(b) => crate::_Wrappers_Compile::Option::Some { + value: blob_to_dafny(&b), + }, + None => crate::_Wrappers_Compile::Option::None {}, + }; + ::std::rc::Rc::new(dafny_value) +} + +pub fn blob_from_dafny(input: ::dafny_runtime::Sequence) -> ::aws_smithy_types::Blob { + ::aws_smithy_types::Blob::new( + ::std::rc::Rc::try_unwrap(input.to_array()).unwrap_or_else(|rc| (*rc).clone()), + ) +} + +pub fn oblob_from_dafny( + input: ::std::rc::Rc>>, +) -> Option<::aws_smithy_types::Blob> { + if matches!( + input.as_ref(), + crate::_Wrappers_Compile::Option::Some { .. } + ) { + Some(blob_from_dafny(input.Extract())) + } else { + None + } +} + +pub fn double_to_dafny(input: f64) -> ::dafny_runtime::Sequence { + ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence( + &f64::to_be_bytes(input).to_vec(), + |x| *x, + ) +} + +pub fn odouble_to_dafny( + input: &Option, +) -> ::std::rc::Rc>> { + let dafny_value = match input { + Some(f) => crate::_Wrappers_Compile::Option::Some { + value: double_to_dafny(*f), + }, + None => crate::_Wrappers_Compile::Option::None {}, + }; + ::std::rc::Rc::new(dafny_value) +} + +pub fn double_from_dafny(input: &::dafny_runtime::Sequence) -> f64 { + let v = ::dafny_runtime::dafny_runtime_conversions::dafny_sequence_to_vec(input, |x| *x); + f64::from_be_bytes(v.try_into().expect("Error converting Sequence to f64")) +} + +pub fn odouble_from_dafny( + input: ::std::rc::Rc>>, +) -> Option { + if matches!( + input.as_ref(), + crate::_Wrappers_Compile::Option::Some { .. } + ) { + Some(double_from_dafny(&input.Extract())) + } else { + None + } +} + +pub fn timestamp_to_dafny( + input: &::aws_smithy_types::DateTime, +) -> ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16> { + ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &input.to_string(), + ) +} + +pub fn otimestamp_to_dafny( + input: &Option<::aws_smithy_types::DateTime>, +) -> ::std::rc::Rc< + crate::_Wrappers_Compile::Option<::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>>, +> { + let dafny_value = match input { + Some(f) => crate::_Wrappers_Compile::Option::Some { + value: timestamp_to_dafny(f), + }, + None => crate::_Wrappers_Compile::Option::None {}, + }; + ::std::rc::Rc::new(dafny_value) +} + +pub fn timestamp_from_dafny( + input: ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, +) -> ::aws_smithy_types::DateTime { + let s = dafny_runtime::dafny_runtime_conversions::unicode_chars_false::dafny_string_to_string( + &input, + ); + ::aws_smithy_types::DateTime::from_str(&s, aws_smithy_types::date_time::Format::DateTime) + .unwrap() +} + +pub fn otimestamp_from_dafny( + input: ::std::rc::Rc< + crate::_Wrappers_Compile::Option< + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + >, +) -> Option<::aws_smithy_types::DateTime> { + if matches!( + input.as_ref(), + crate::_Wrappers_Compile::Option::Some { .. } + ) { + Some(timestamp_from_dafny(input.Extract())) + } else { + None + } +} + +pub fn option_from_dafny( + input: ::std::rc::Rc>, + converter: fn(&T) -> TR, +) -> Option { + match &*input { + crate::_Wrappers_Compile::Option::Some { value } => Some(converter(value)), + crate::_Wrappers_Compile::Option::None {} => None, + } +} + +pub fn option_to_dafny( + input: &Option, + converter: fn(&TR) -> T, +) -> ::std::rc::Rc> { + match input { + Some(value) => ::std::rc::Rc::new(crate::_Wrappers_Compile::Option::Some { + value: converter(&value), + }), + None => ::std::rc::Rc::new(crate::_Wrappers_Compile::Option::None {}), + } +} + +pub fn result_from_dafny( + input: ::std::rc::Rc>, + converter_t: fn(&T) -> TR, + converter_e: fn(&E) -> ER, +) -> Result { + match &*input { + crate::_Wrappers_Compile::Result::Success { value } => Ok(converter_t(value)), + crate::_Wrappers_Compile::Result::Failure { error } => Err(converter_e(error)), + } +} + +pub fn result_to_dafny( + input: &Result, + converter_t: fn(&TR) -> T, + converter_e: fn(&ER) -> E, +) -> ::std::rc::Rc> { + match input { + Ok(value) => ::std::rc::Rc::new(crate::_Wrappers_Compile::Result::Success { + value: converter_t(&value), + }), + Err(error) => ::std::rc::Rc::new(crate::_Wrappers_Compile::Result::Failure { + error: converter_e(&error), + }), + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/standard_library_externs.rs b/TestModels/Constraints/runtimes/rust/src/standard_library_externs.rs new file mode 100644 index 000000000..eca6a2980 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/standard_library_externs.rs @@ -0,0 +1,80 @@ +// Annotation to ignore the case of this module +use crate::r#_Wrappers_Compile; +use crate::UTF8; + +impl crate::UTF8::_default { + pub fn Encode( + s: &::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ) -> ::std::rc::Rc< + r#_Wrappers_Compile::Result< + UTF8::ValidUTF8Bytes, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let v = s.to_array(); + let mut _accumulator: Vec = vec![]; + // Use of .encode_utf8 method. + let mut surrogate: Option = None; + for c in v.iter() { + let s = if let Some(s) = surrogate { + String::from_utf16(&[s, c.0]) + } else { + String::from_utf16(&[c.0]) + }; + surrogate = None; + match s { + Ok(value) => { + _accumulator.extend(value.as_bytes()); + continue; + } + Err(e) => { + if 0xD800 <= c.0 && c.0 <= 0xDFFF { + surrogate = Some(c.0); + continue; + } + return ::std::rc::Rc::new(r#_Wrappers_Compile::Result::>::Failure { + error: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &e.to_string()) + }); + } + } + } + if let Some(s) = surrogate { + return ::std::rc::Rc::new(r#_Wrappers_Compile::Result::>::Failure { + error: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &format!("Surrogate pair missing: 0x{:04x}", s)) + }); + } + ::std::rc::Rc::new(r#_Wrappers_Compile::Result::< + UTF8::ValidUTF8Bytes, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >::Success { + value: ::dafny_runtime::Sequence::from_array_owned(_accumulator), + }) + } + pub fn Decode( + b: &::dafny_runtime::Sequence, + ) -> ::std::rc::Rc< + r#_Wrappers_Compile::Result< + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + >, + > { + let b = String::from_utf8(b.to_array().as_ref().clone()); + match b { + Ok(s) => { + ::std::rc::Rc::new(r#_Wrappers_Compile::Result::<::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>>::Success { + value: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&s) + }) + }, + Err(e) => { + return ::std::rc::Rc::new(r#_Wrappers_Compile::Result::<::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>, + ::dafny_runtime::Sequence<::dafny_runtime::DafnyCharUTF16>>::Failure { + error: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string( + &e.to_string()) + }) + } + } + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/types.rs b/TestModels/Constraints/runtimes/rust/src/types.rs new file mode 100644 index 000000000..1d954e08e --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/types.rs @@ -0,0 +1,16 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +/// Types for the `SimpleConstraintsConfig` +pub mod simple_constraints_config; + +pub mod builders; + + + + + +pub mod error; + + + diff --git a/TestModels/Constraints/runtimes/rust/src/types/builders.rs b/TestModels/Constraints/runtimes/rust/src/types/builders.rs new file mode 100644 index 000000000..5fbbbaa0f --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/types/builders.rs @@ -0,0 +1,3 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. diff --git a/TestModels/Constraints/runtimes/rust/src/types/error.rs b/TestModels/Constraints/runtimes/rust/src/types/error.rs new file mode 100644 index 000000000..ddbfc4b42 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/types/error.rs @@ -0,0 +1,67 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[derive(::std::clone::Clone, ::std::fmt::Debug, ::std::cmp::PartialEq)] +pub enum Error { + SimpleConstraintsException { + message: ::std::string::String, +}, + CollectionOfErrors { + list: ::std::vec::Vec, + message: ::std::string::String, + }, + ValidationError(ValidationError), + Opaque { + obj: ::dafny_runtime::Object, + }, +} + +impl ::std::cmp::Eq for Error {} + +impl ::std::fmt::Display for Error { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + match self { + Self::ValidationError(err) => ::std::fmt::Display::fmt(err, f), + _ => ::std::fmt::Debug::fmt(self, f), + } + } +} + +impl ::std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::ValidationError(err) => Some(err), + _ => None, + } + } +} + +impl Error { + pub fn wrap_validation_err(err: E) -> Self + where + E: ::std::error::Error + 'static, + { + Self::ValidationError(ValidationError(::std::rc::Rc::new(err))) + } +} + +#[derive(::std::clone::Clone, ::std::fmt::Debug)] +pub(crate) struct ValidationError(::std::rc::Rc); + +impl ::std::cmp::PartialEq for ValidationError { + fn eq(&self, other: &Self) -> bool { + ::std::rc::Rc::<(dyn std::error::Error + 'static)>::ptr_eq(&self.0, &other.0) + } +} + +impl ::std::fmt::Display for ValidationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + ::std::fmt::Display::fmt(&self.0, f) + } +} + +impl ::std::error::Error for ValidationError { + fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> { + ::std::option::Option::Some(self.0.as_ref()) + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/types/simple_constraints_config.rs b/TestModels/Constraints/runtimes/rust/src/types/simple_constraints_config.rs new file mode 100644 index 000000000..84b1e17a4 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/types/simple_constraints_config.rs @@ -0,0 +1,41 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +#[allow(missing_docs)] // documentation missing in model +#[non_exhaustive] +#[derive(::std::clone::Clone, ::std::cmp::PartialEq, ::std::fmt::Debug)] +pub struct SimpleConstraintsConfig { + +} +impl SimpleConstraintsConfig { + +} +impl SimpleConstraintsConfig { + /// Creates a new builder-style object to manufacture [`SimpleConstraintsConfig`](crate::types::SimpleConstraintsConfig). + pub fn builder() -> crate::types::simple_constraints_config::SimpleConstraintsConfigBuilder { + crate::types::simple_constraints_config::SimpleConstraintsConfigBuilder::default() + } +} + +/// A builder for [`SimpleConstraintsConfig`](crate::types::SimpleConstraintsConfig). +#[non_exhaustive] +#[derive( + ::std::clone::Clone, ::std::cmp::PartialEq, ::std::default::Default, ::std::fmt::Debug, +)] +pub struct SimpleConstraintsConfigBuilder { + +} +impl SimpleConstraintsConfigBuilder { + + /// Consumes the builder and constructs a [`SimpleConstraintsConfig`](crate::types::SimpleConstraintsConfig). + pub fn build( + self, + ) -> ::std::result::Result< + crate::types::simple_constraints_config::SimpleConstraintsConfig, + ::aws_smithy_types::error::operation::BuildError, + > { + ::std::result::Result::Ok(crate::types::simple_constraints_config::SimpleConstraintsConfig { + + }) + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/wrapped.rs b/TestModels/Constraints/runtimes/rust/src/wrapped.rs new file mode 100644 index 000000000..b8a6bc85e --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/wrapped.rs @@ -0,0 +1,15 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +pub mod client; + +impl crate::r#simple::constraints::internaldafny::wrapped::_default { + pub fn WrappedSimpleConstraints(config: &::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig, + >) -> ::std::rc::Rc, + ::std::rc::Rc + >>{ + crate::wrapped::client::Client::from_conf(config) + } +} diff --git a/TestModels/Constraints/runtimes/rust/src/wrapped/client.rs b/TestModels/Constraints/runtimes/rust/src/wrapped/client.rs new file mode 100644 index 000000000..72019bbaf --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/src/wrapped/client.rs @@ -0,0 +1,83 @@ +// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// Do not modify this file. This file is machine generated, and any changes to it will be overwritten. +use std::sync::LazyLock; + +pub struct Client { + wrapped: crate::client::Client +} + +/// A runtime for executing operations on the asynchronous client in a blocking manner. +/// Necessary because Dafny only generates synchronous code. +static dafny_tokio_runtime: LazyLock = LazyLock::new(|| { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +}); + +impl dafny_runtime::UpcastObject for Client { + ::dafny_runtime::UpcastObjectFn!(dyn crate::r#simple::constraints::internaldafny::types::ISimpleConstraintsClient); +} + +impl dafny_runtime::UpcastObject for Client { + ::dafny_runtime::UpcastObjectFn!(dyn ::std::any::Any); +} + +impl Client { + pub fn from_conf(config: &::std::rc::Rc< + crate::r#simple::constraints::internaldafny::types::SimpleConstraintsConfig, + >) -> +::std::rc::Rc, + ::std::rc::Rc +>> { + let result = crate::client::Client::from_conf( + crate::conversions::simple_constraints_config::_simple_constraints_config::from_dafny( + config.clone(), + ), + ); + match result { + Ok(client) => { + let wrap = crate::wrapped::client::Client { + wrapped: client + }; + std::rc::Rc::new( + crate::_Wrappers_Compile::Result::Success { + value: ::dafny_runtime::upcast_object()(::dafny_runtime::object::new(wrap)) + } + ) + }, + Err(error) => crate::conversions::error::to_opaque_error_result(error) + } + } +} + +impl crate::r#simple::constraints::internaldafny::types::ISimpleConstraintsClient for Client { + fn GetConstraints( + &mut self, + input: &::std::rc::Rc, + ) -> std::rc::Rc< + crate::r#_Wrappers_Compile::Result< + ::std::rc::Rc, + std::rc::Rc, + >, + >{ + let inner_input = crate::conversions::get_constraints::_get_constraints_input::from_dafny(input.clone()); + let result = tokio::task::block_in_place(|| { + dafny_tokio_runtime.block_on(crate::operation::get_constraints::GetConstraints::send(&self.wrapped, inner_input)) + }); + match result { + Err(error) => ::std::rc::Rc::new( + crate::_Wrappers_Compile::Result::Failure { + error: crate::conversions::error::to_dafny(error), + }, + ), + Ok(inner_result) => ::std::rc::Rc::new( + crate::_Wrappers_Compile::Result::Success { + value: crate::conversions::get_constraints::_get_constraints_output::to_dafny(inner_result), + }, + ), + } + } +} diff --git a/TestModels/Constraints/runtimes/rust/tests/simple_constraints_test.rs b/TestModels/Constraints/runtimes/rust/tests/simple_constraints_test.rs new file mode 100644 index 000000000..7c8168b16 --- /dev/null +++ b/TestModels/Constraints/runtimes/rust/tests/simple_constraints_test.rs @@ -0,0 +1,69 @@ +extern crate simple_constraints; + +/// Smoke tests for constraint validation when calling in from Rust code. +mod simple_constraints_test { + use simple_constraints::*; + + fn client() -> Client { + let config = SimpleConstraintsConfig::builder().build().expect("config"); + client::Client::from_conf(config).expect("client") + } + + #[tokio::test] + async fn test_empty_input() { + let result = client().get_constraints().send().await; + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_short_string() { + let result = client().get_constraints().my_string("").send().await; + let error = result.err().expect("error"); + assert!(matches!( + error, + simple_constraints::types::error::Error::ValidationError(..) + )); + assert!(error.to_string().contains("my_string")); + + use std::error::Error; + let source_message = error.source().expect("source").to_string(); + assert!(source_message.contains("my_string")); + } + + #[tokio::test] + async fn test_good_string() { + let result = client().get_constraints().my_string("good").send().await; + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_long_string() { + let result = client() + .get_constraints() + .my_string("too many characters") + .send() + .await; + let message = result.err().expect("error").to_string(); + assert!(message.contains("my_string")); + } + + #[tokio::test] + async fn test_small_int() { + let result = client().get_constraints().one_to_ten(0).send().await; + let message = result.err().expect("error").to_string(); + assert!(message.contains("one_to_ten")); + } + + #[tokio::test] + async fn test_good_int() { + let result = client().get_constraints().one_to_ten(5).send().await; + assert!(result.is_ok()); + } + + #[tokio::test] + async fn test_big_int() { + let result = client().get_constraints().one_to_ten(99).send().await; + let message = result.err().expect("error").to_string(); + assert!(message.contains("one_to_ten")); + } +} diff --git a/TestModels/Constraints/test/WrappedSimpleConstraintsTest.dfy b/TestModels/Constraints/test/WrappedSimpleConstraintsTest.dfy index dd48a4dbd..d5fc2b327 100644 --- a/TestModels/Constraints/test/WrappedSimpleConstraintsTest.dfy +++ b/TestModels/Constraints/test/WrappedSimpleConstraintsTest.dfy @@ -31,6 +31,12 @@ module WrappedSimpleConstraintsTest { TestGetConstraintWithGreaterThanOne(client); TestGetConstraintWithUtf8Bytes(client); TestGetConstraintWithListOfUtf8Bytes(client); + + var allowBadUtf8BytesFromDafny := true; + if (allowBadUtf8BytesFromDafny) { + TestGetConstraintWithBadUtf8Bytes(client); + TestGetConstraintWithListOfBadUtf8Bytes(client); + } } method TestGetConstraintWithValidInputs(client: ISimpleConstraintsClient) @@ -486,11 +492,6 @@ module WrappedSimpleConstraintsTest { ret := client.GetConstraints(input := input); expect ret.Failure?; - // good length, bad bytes - input := input.(MyUtf8Bytes := Some(ForceUtf8Bytes([255,255,255]))); - ret := client.GetConstraints(input := input); - expect ret.Failure?; - var one : seq := [0xf0, 0xa8, 0x89, 0x9f]; var two : seq := [0xc2, 0xa3]; input := input.(MyUtf8Bytes := Some(ForceUtf8Bytes(one))); @@ -527,13 +528,25 @@ module WrappedSimpleConstraintsTest { // expect ret.Failure?; } + // @length(min: 1, max: 10) + method TestGetConstraintWithBadUtf8Bytes(client: ISimpleConstraintsClient) + requires client.ValidState() + modifies client.Modifies + ensures client.ValidState() + { + // good length, bad bytes + var input := GetValidInput(); + input := input.(MyUtf8Bytes := Some(ForceUtf8Bytes([255,255,255]))); + var ret := client.GetConstraints(input := input); + expect ret.Failure?; + } + // @length(min: 1, max: 2) method TestGetConstraintWithListOfUtf8Bytes(client: ISimpleConstraintsClient) requires client.ValidState() modifies client.Modifies ensures client.ValidState() { - var bad := ForceUtf8Bytes([255,255,255]); var good := ForceUtf8Bytes([1,2,3]); var input := GetValidInput(); @@ -552,9 +565,20 @@ module WrappedSimpleConstraintsTest { input := input.(MyListOfUtf8Bytes := Some(ForceListOfUtf8Bytes([good, good, good]))); ret := client.GetConstraints(input := input); expect ret.Failure?; + } + // @length(min: 1, max: 2) + method TestGetConstraintWithListOfBadUtf8Bytes(client: ISimpleConstraintsClient) + requires client.ValidState() + modifies client.Modifies + ensures client.ValidState() + { + var bad := ForceUtf8Bytes([255,255,255]); + var good := ForceUtf8Bytes([1,2,3]); + + var input := GetValidInput(); input := input.(MyListOfUtf8Bytes := Some(ForceListOfUtf8Bytes([bad]))); - ret := client.GetConstraints(input := input); + var ret := client.GetConstraints(input := input); expect ret.Failure?; input := input.(MyListOfUtf8Bytes := Some(ForceListOfUtf8Bytes([bad, good]))); @@ -565,4 +589,4 @@ module WrappedSimpleConstraintsTest { ret := client.GetConstraints(input := input); expect ret.Failure?; } -} \ No newline at end of file +} diff --git a/TestModels/Positional/runtimes/rust/src/conversions/error.rs b/TestModels/Positional/runtimes/rust/src/conversions/error.rs index e405b691a..a24385b0b 100644 --- a/TestModels/Positional/runtimes/rust/src/conversions/error.rs +++ b/TestModels/Positional/runtimes/rust/src/conversions/error.rs @@ -41,6 +41,16 @@ pub fn to_dafny( message: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&message), list: ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&list, |e| to_dafny(e.clone())) }, + crate::types::error::Error::ValidationError(inner) => + crate::r#simple::positional::internaldafny::types::Error::Opaque { + obj: { + let rc = ::std::rc::Rc::new(inner) as ::std::rc::Rc; + // safety: `rc` is new, ensuring it has refcount 1 and is uniquely owned. + // we should use `dafny_runtime_conversions::rc_struct_to_dafny_class` once it + // accepts unsized types (https://github.com/dafny-lang/dafny/pull/5769) + unsafe { ::dafny_runtime::Object::from_rc(rc) } + }, + }, crate::types::error::Error::Opaque { obj } => crate::r#simple::positional::internaldafny::types::Error::Opaque { obj: ::dafny_runtime::Object(obj.0) @@ -68,5 +78,22 @@ pub fn from_dafny( crate::types::error::Error::Opaque { obj: obj.clone() }, + crate::r#simple::positional::internaldafny::types::Error::Opaque { obj } => + { + use ::std::any::Any; + if ::dafny_runtime::is_object!(obj, crate::types::error::ValidationError) { + let typed = ::dafny_runtime::cast_object!(obj.clone(), crate::types::error::ValidationError); + crate::types::error::Error::ValidationError( + // safety: dafny_class_to_struct will increment ValidationError's Rc + unsafe { + ::dafny_runtime::dafny_runtime_conversions::object::dafny_class_to_struct(typed) + } + ) + } else { + crate::types::error::Error::Opaque { + obj: obj.clone() + } + } + }, } } diff --git a/TestModels/Positional/runtimes/rust/src/operation/get_name.rs b/TestModels/Positional/runtimes/rust/src/operation/get_name.rs index f23b3967e..6952c937e 100644 --- a/TestModels/Positional/runtimes/rust/src/operation/get_name.rs +++ b/TestModels/Positional/runtimes/rust/src/operation/get_name.rs @@ -10,6 +10,7 @@ impl GetName { pub fn new() -> Self { Self } + pub(crate) async fn send( simple_resource: &crate::types::simple_resource::SimpleResourceRef, input: crate::operation::get_name::GetNameInput, @@ -17,6 +18,7 @@ impl GetName { crate::operation::get_name::GetNameOutput, crate::types::error::Error, > { + simple_resource.inner.borrow_mut().get_name(input) } } diff --git a/TestModels/Positional/runtimes/rust/src/operation/get_resource.rs b/TestModels/Positional/runtimes/rust/src/operation/get_resource.rs index 40abe7006..cc11676e4 100644 --- a/TestModels/Positional/runtimes/rust/src/operation/get_resource.rs +++ b/TestModels/Positional/runtimes/rust/src/operation/get_resource.rs @@ -10,6 +10,7 @@ impl GetResource { pub fn new() -> Self { Self } + pub(crate) async fn send( client: &crate::client::Client, input: crate::operation::get_resource::GetResourceInput, @@ -17,6 +18,12 @@ impl GetResource { crate::operation::get_resource::GetResourceOutput, crate::types::error::Error, > { + if input.name.is_none() { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::missing_field( + "name", + "name was not specified but it is required when building GetResourceInput", + )).map_err(crate::types::error::Error::wrap_validation_err); +} let inner_input = crate::conversions::get_resource::_get_resource_input::to_dafny(input); let inner_result = ::dafny_runtime::md!(client.dafny_client.clone()).GetResource(&inner_input); diff --git a/TestModels/Positional/runtimes/rust/src/operation/get_resource_positional.rs b/TestModels/Positional/runtimes/rust/src/operation/get_resource_positional.rs index 4176e439b..9fb668a91 100644 --- a/TestModels/Positional/runtimes/rust/src/operation/get_resource_positional.rs +++ b/TestModels/Positional/runtimes/rust/src/operation/get_resource_positional.rs @@ -10,6 +10,7 @@ impl GetResourcePositional { pub fn new() -> Self { Self } + pub(crate) async fn send( client: &crate::client::Client, input: crate::operation::get_resource_positional::GetResourcePositionalInput, @@ -17,6 +18,12 @@ impl GetResourcePositional { crate::types::simple_resource::SimpleResourceRef, crate::types::error::Error, > { + if input.name.is_none() { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::missing_field( + "name", + "name was not specified but it is required when building GetResourcePositionalInput", + )).map_err(crate::types::error::Error::wrap_validation_err); +} let inner_input = crate::standard_library_conversions::ostring_to_dafny(&input.name) .Extract(); let inner_result = ::dafny_runtime::md!(client.dafny_client.clone()).GetResourcePositional(&inner_input); diff --git a/TestModels/Positional/runtimes/rust/src/types/error.rs b/TestModels/Positional/runtimes/rust/src/types/error.rs index 347e32214..4100dbd36 100644 --- a/TestModels/Positional/runtimes/rust/src/types/error.rs +++ b/TestModels/Positional/runtimes/rust/src/types/error.rs @@ -7,9 +7,10 @@ pub enum Error { message: ::std::string::String, }, CollectionOfErrors { - list: ::std::vec::Vec, + list: ::std::vec::Vec, message: ::std::string::String, }, + ValidationError(ValidationError), Opaque { obj: ::dafny_runtime::Object, }, @@ -19,8 +20,48 @@ impl ::std::cmp::Eq for Error {} impl ::std::fmt::Display for Error { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(f, "{:?}", self) + match self { + Self::ValidationError(err) => ::std::fmt::Display::fmt(err, f), + _ => ::std::fmt::Debug::fmt(self, f), + } } } -impl ::std::error::Error for Error {} +impl ::std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::ValidationError(err) => Some(err), + _ => None, + } + } +} + +impl Error { + pub fn wrap_validation_err(err: E) -> Self + where + E: ::std::error::Error + 'static, + { + Self::ValidationError(ValidationError(::std::rc::Rc::new(err))) + } +} + +#[derive(::std::clone::Clone, ::std::fmt::Debug)] +pub(crate) struct ValidationError(::std::rc::Rc); + +impl ::std::cmp::PartialEq for ValidationError { + fn eq(&self, other: &Self) -> bool { + ::std::rc::Rc::<(dyn std::error::Error + 'static)>::ptr_eq(&self.0, &other.0) + } +} + +impl ::std::fmt::Display for ValidationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + ::std::fmt::Display::fmt(&self.0, f) + } +} + +impl ::std::error::Error for ValidationError { + fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> { + ::std::option::Option::Some(self.0.as_ref()) + } +} diff --git a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/AbstractRustShimGenerator.java b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/AbstractRustShimGenerator.java index 7854660e2..5de4db741 100644 --- a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/AbstractRustShimGenerator.java +++ b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/AbstractRustShimGenerator.java @@ -463,7 +463,10 @@ protected TokenTree fromDafny( valueToRust = "(%s).unwrap()".formatted(valueToRust); } } else { - valueToRust = dafnyToRust.formatted(dafnyValue + ".as_ref()"); + valueToRust = + dafnyToRust.formatted( + "::std::borrow::Borrow::borrow(%s)".formatted(dafnyValue) + ); if (isRustOption) { valueToRust = "Some(%s)".formatted(valueToRust); } diff --git a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/RustLibraryShimGenerator.java b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/RustLibraryShimGenerator.java index a1a87b777..27e2a8556 100644 --- a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/RustLibraryShimGenerator.java +++ b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/RustLibraryShimGenerator.java @@ -4,6 +4,7 @@ import static software.amazon.smithy.rust.codegen.core.util.StringsKt.toPascalCase; import static software.amazon.smithy.rust.codegen.core.util.StringsKt.toSnakeCase; +import java.math.BigDecimal; import java.nio.file.Path; import java.util.Collection; import java.util.HashMap; @@ -13,11 +14,10 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; import software.amazon.polymorph.traits.DafnyUtf8BytesTrait; import software.amazon.polymorph.traits.LocalServiceTrait; import software.amazon.polymorph.traits.PositionalTrait; -import software.amazon.polymorph.traits.ReferenceTrait; +import software.amazon.polymorph.utils.ConstrainTraitUtils; import software.amazon.polymorph.utils.IOUtils; import software.amazon.polymorph.utils.MapUtils; import software.amazon.polymorph.utils.ModelUtils; @@ -36,6 +36,8 @@ import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.shapes.UnionShape; import software.amazon.smithy.model.traits.EnumTrait; +import software.amazon.smithy.model.traits.LengthTrait; +import software.amazon.smithy.model.traits.RangeTrait; /** * Generates all Rust modules needed to wrap a Dafny library as a Rust library. @@ -614,25 +616,31 @@ private Set operationImplementationModules( StructureShape.class ); return Set.of( - operationOuterModule(operationShape), + operationOuterModule(operationShape, inputShape), operationStructureModule(operationShape, inputShape), operationStructureModule(operationShape, outputShape), operationBuildersModule(operationShape) ); } - private RustFile operationOuterModule(final OperationShape operationShape) { - Map variables = MapUtils.merge( + private RustFile operationOuterModule( + final OperationShape operationShape, + final StructureShape inputShape + ) { + final Shape bindingShape = operationBindingIndex + .getBindingShape(operationShape) + .orElseThrow(); + final Map variables = MapUtils.merge( serviceVariables(), operationVariables(operationShape) ); - final Shape bindingShape = operationBindingIndex - .getBindingShape(operationShape) - .get(); + variables.put( + "inputValidations", + new InputValidationGenerator(operationShape) + .generateValidations(model, inputShape) + .collect(Collectors.joining("\n")) + ); if (bindingShape.isServiceShape()) { - StructureShape inputShape = operationIndex - .getInputShape(operationShape) - .get(); if (inputShape.hasTrait(PositionalTrait.class)) { // Need to fetch the single member and then convert, // since on the Rust side there is still an input structure @@ -687,7 +695,7 @@ private RustFile operationOuterModule(final OperationShape operationShape) { "$snakeCaseResourceName:L.inner.borrow_mut().$snakeCaseOperationName:L(input)", MapUtils.merge( variables, - resourceVariables(bindingShape.asResourceShape().get()) + resourceVariables(bindingShape.asResourceShape().orElseThrow()) ) ) ); @@ -705,6 +713,138 @@ private RustFile operationOuterModule(final OperationShape operationShape) { return new RustFile(path, TokenTree.of(content)); } + class InputValidationGenerator + extends ConstrainTraitUtils.ValidationGenerator { + + private final Map commonVariables; + + InputValidationGenerator(final OperationShape operationShape) { + this.commonVariables = + MapUtils.merge(serviceVariables(), operationVariables(operationShape)); + } + + @Override + protected String validateRequired(final MemberShape memberShape) { + return IOUtils.evalTemplate( + """ + if input.$fieldName:L.is_none() { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::missing_field( + "$fieldName:L", + "$fieldName:L was not specified but it is required when building $pascalCaseOperationInputName:L", + )).map_err($qualifiedRustServiceErrorType:L::wrap_validation_err); + } + """, + MapUtils.merge(commonVariables, structureMemberVariables(memberShape)) + ); + } + + @Override + protected String validateRange( + final MemberShape memberShape, + final RangeTrait rangeTrait + ) { + final var variables = MapUtils.merge( + commonVariables, + structureMemberVariables(memberShape) + ); + final var targetShape = model.expectShape(memberShape.getTarget()); + final var min = rangeTrait + .getMin() + .map(bound -> asLiteral(bound, targetShape)); + final var max = rangeTrait + .getMax() + .map(bound -> asLiteral(bound, targetShape)); + final var conditionTemplate = + "!(%s..%s).contains(&x)".formatted( + min.orElse(""), + max.map(val -> "=" + val).orElse("") + ); + final var rangeDescription = describeMinMax(min, max); + return IOUtils.evalTemplate( + """ + if matches!(input.$fieldName:L, Some(x) if %s) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "$fieldName:L", + "$fieldName:L failed to satisfy constraint: Member must be %s", + )).map_err($qualifiedRustServiceErrorType:L::wrap_validation_err); + } + """.formatted(conditionTemplate, rangeDescription), + variables + ); + } + + @Override + protected String validateLength( + final MemberShape memberShape, + final LengthTrait lengthTrait + ) { + final var targetShape = model.expectShape(memberShape.getTarget()); + final var len = + switch (targetShape.getType()) { + case BLOB -> "x.as_ref().len()"; + case STRING -> targetShape.hasTrait(DafnyUtf8BytesTrait.class) + // scalar values + ? "x.chars().count()" + // The Smithy spec says that this should count scalar values, + // but for consistency with the existing Java and .NET implementations, + // we instead count UTF-16 code points. + // See . + : "x.chars().map(::std::primitive::char::len_utf16).fold(0usize, ::std::ops::Add::add)"; + default -> "x.len()"; + }; + final var variables = MapUtils.merge( + commonVariables, + structureMemberVariables(memberShape) + ); + final var min = lengthTrait.getMin().map(Object::toString); + final var max = lengthTrait.getMax().map(Object::toString); + final var conditionTemplate = + "!(%s..%s).contains(&%s)".formatted( + min.orElse(""), + max.map(val -> "=" + val).orElse(""), + len + ); + final var rangeDescription = describeMinMax(min, max); + return IOUtils.evalTemplate( + """ + if matches!(input.$fieldName:L, Some(ref x) if %s) { + return ::std::result::Result::Err(::aws_smithy_types::error::operation::BuildError::invalid_field( + "$fieldName:L", + "$fieldName:L failed to satisfy constraint: Member must have length %s", + )).map_err($qualifiedRustServiceErrorType:L::wrap_validation_err); + } + """.formatted(conditionTemplate, rangeDescription), + variables + ); + } + + private String asLiteral(final BigDecimal value, final Shape targetShape) { + return ConstrainTraitUtils.RangeTraitUtils.asShapeType( + targetShape, + value + ); + } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private String describeMinMax( + final Optional min, + final Optional max + ) { + if (min.isPresent() && max.isPresent()) { + return "between %s and %s, inclusive".formatted(min.get(), max.get()); + } else if (min.isPresent()) { + return "greater than or equal to %s".formatted(min.get()); + } else { + if (max.isEmpty()) { + throw new IllegalArgumentException( + "At least one of max and min must be non-null" + ); + } + return "less than or equal to %s".formatted(max.get()); + } + } + } + private RustFile operationStructureModule( final OperationShape operationShape, final StructureShape structureShape @@ -1457,6 +1597,7 @@ protected HashMap serviceVariables() { variables.put("sdkId", sdkId); variables.put("configName", configName); variables.put("snakeCaseConfigName", toSnakeCase(configName)); + variables.put("rustErrorModuleName", rustErrorModuleName()); variables.put( "qualifiedRustServiceErrorType", qualifiedRustServiceErrorType() @@ -1497,8 +1638,12 @@ private HashMap structureMemberVariables( return variables; } + protected String rustErrorModuleName() { + return "%s::error".formatted(getRustTypesModuleName()); + } + protected String qualifiedRustServiceErrorType() { - return "%s::error::Error".formatted(getRustTypesModuleName()); + return "%s::Error".formatted(rustErrorModuleName()); } protected String errorName(final StructureShape errorShape) { @@ -1582,21 +1727,17 @@ protected TokenTree toDafny( } else if (shape.hasTrait(DafnyUtf8BytesTrait.class)) { final String rustToDafny = "dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&%s.as_bytes().to_vec(), |b| *b)"; - String valueToDafny; - if (isRustOption) { - valueToDafny = - """ - match %s { - Some(s) => crate::_Wrappers_Compile::Option::Some { value: %s }, - None => crate::_Wrappers_Compile::Option::None {}, - }""".formatted(rustValue, rustToDafny.formatted("s")); - if (!isDafnyOption) { - valueToDafny = "(%s).Extract()".formatted(valueToDafny); - } - } else { - valueToDafny = rustToDafny.formatted(rustValue); + if (!isRustOption) { + yield TokenTree.of(rustToDafny.formatted(rustValue)); } - yield TokenTree.of("::std::rc::Rc::new(%s)".formatted(valueToDafny)); + final String coercion = isDafnyOption ? "into()" : "Extract()"; + yield TokenTree.of( + """ + (match %s { + Some(s) => crate::_Wrappers_Compile::Option::Some { value: %s }, + None => crate::_Wrappers_Compile::Option::None {}, + }).%s""".formatted(rustValue, rustToDafny.formatted("s"), coercion) + ); } else { if (isRustOption) { var result = TokenTree.of( diff --git a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/utils/ConstrainTraitUtils.java b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/utils/ConstrainTraitUtils.java index 0ca2c5774..66ea60976 100644 --- a/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/utils/ConstrainTraitUtils.java +++ b/codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/utils/ConstrainTraitUtils.java @@ -3,10 +3,17 @@ package software.amazon.polymorph.utils; import java.math.BigDecimal; +import java.util.Optional; +import java.util.stream.Stream; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.MemberShape; import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.StructureShape; import software.amazon.smithy.model.traits.LengthTrait; import software.amazon.smithy.model.traits.RangeTrait; import software.amazon.smithy.model.traits.RequiredTrait; +import software.amazon.smithy.model.traits.Trait; +import software.amazon.smithy.utils.Pair; // TODO: Support idRef, pattern, uniqueItems public class ConstrainTraitUtils { @@ -29,6 +36,72 @@ public static boolean hasConstraintTrait(Shape shape) { ); } + /** + * Utility class to generate validation expressions for all members of a structure. + * + * @param type of validation expressions, typically {@link String} or {@link TokenTree} + */ + public abstract static class ValidationGenerator { + + protected abstract V validateRequired(MemberShape memberShape); + + protected abstract V validateRange( + MemberShape memberShape, + RangeTrait rangeTrait + ); + + protected abstract V validateLength( + MemberShape memberShape, + LengthTrait lengthTrait + ); + + /** + * Returns a stream of constraint traits that Polymorph-generated code should enforce + * on any code path that invokes a service or resource operation, + * from either the given shape or the targeted shape (if the given shape is a member shape). + */ + private Stream enforcedConstraints( + final Model model, + final Shape shape + ) { + return Stream + .of( + shape.getMemberTrait(model, RequiredTrait.class), + shape.getMemberTrait(model, RangeTrait.class), + shape.getMemberTrait(model, LengthTrait.class) + ) + .flatMap(Optional::stream); + } + + public Stream generateValidations( + final Model model, + final StructureShape structureShape + ) { + return structureShape + .getAllMembers() + .values() + .stream() + .flatMap(memberShape -> + enforcedConstraints(model, memberShape) + .map(trait -> Pair.of(memberShape, trait)) + ) + .map(memberTrait -> { + final MemberShape memberShape = memberTrait.left; + final Trait trait = memberTrait.right; + if (trait instanceof RequiredTrait) { + return validateRequired(memberShape); + } else if (trait instanceof RangeTrait rangeTrait) { + return validateRange(memberShape, rangeTrait); + } else if (trait instanceof LengthTrait lengthTrait) { + return validateLength(memberShape, lengthTrait); + } + throw new UnsupportedOperationException( + "Unsupported constraint trait %s on shape %s".formatted(trait) + ); + }); + } + } + public static class RangeTraitUtils { /** Return the trait's min as an accurate string representation @@ -50,7 +123,7 @@ public static String maxAsShapeType(Shape shape, RangeTrait trait) { } // TODO: Only INTEGER has been tested - private static String asShapeType(Shape shape, BigDecimal value) { + public static String asShapeType(Shape shape, BigDecimal value) { return switch (shape.getType()) { case BYTE -> "%d".formatted(value.byteValue()); case SHORT -> "%d".formatted(value.shortValue()); diff --git a/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/conversions/error_library.rs b/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/conversions/error_library.rs index 6a9dbacc7..2f37db65b 100644 --- a/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/conversions/error_library.rs +++ b/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/conversions/error_library.rs @@ -9,6 +9,16 @@ pub fn to_dafny( message: ::dafny_runtime::dafny_runtime_conversions::unicode_chars_false::string_to_dafny_string(&message), list: ::dafny_runtime::dafny_runtime_conversions::vec_to_dafny_sequence(&list, |e| to_dafny(e.clone())) }, + $qualifiedRustServiceErrorType:L::ValidationError(inner) => + crate::r#$dafnyTypesModuleName:L::Error::Opaque { + obj: { + let rc = ::std::rc::Rc::new(inner) as ::std::rc::Rc; + // safety: `rc` is new, ensuring it has refcount 1 and is uniquely owned. + // we should use `dafny_runtime_conversions::rc_struct_to_dafny_class` once it + // accepts unsized types (https://github.com/dafny-lang/dafny/pull/5769) + unsafe { ::dafny_runtime::Object::from_rc(rc) } + }, + }, $qualifiedRustServiceErrorType:L::Opaque { obj } => crate::r#$dafnyTypesModuleName:L::Error::Opaque { obj: ::dafny_runtime::Object(obj.0) @@ -33,5 +43,22 @@ pub fn from_dafny( $qualifiedRustServiceErrorType:L::Opaque { obj: obj.clone() }, + crate::r#$dafnyTypesModuleName:L::Error::Opaque { obj } => + { + use ::std::any::Any; + if ::dafny_runtime::is_object!(obj, $rustErrorModuleName:L::ValidationError) { + let typed = ::dafny_runtime::cast_object!(obj.clone(), $rustErrorModuleName:L::ValidationError); + $qualifiedRustServiceErrorType:L::ValidationError( + // safety: dafny_class_to_struct will increment ValidationError's Rc + unsafe { + ::dafny_runtime::dafny_runtime_conversions::object::dafny_class_to_struct(typed) + } + ) + } else { + $qualifiedRustServiceErrorType:L::Opaque { + obj: obj.clone() + } + } + }, } } \ No newline at end of file diff --git a/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/operation/outer.rs b/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/operation/outer.rs index cac908666..4fe07443f 100644 --- a/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/operation/outer.rs +++ b/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/operation/outer.rs @@ -7,6 +7,7 @@ impl $pascalCaseOperationName:L { pub fn new() -> Self { Self } + pub(crate) async fn send( $operationTargetName:L: &$operationTargetType:L, input: $operationInputType:L, @@ -14,6 +15,7 @@ impl $pascalCaseOperationName:L { $operationOutputType:L, $qualifiedRustServiceErrorType:L, > { + $inputValidations:L $operationSendBody:L } } diff --git a/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/types/error.rs b/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/types/error.rs index 9969313fa..931d03303 100644 --- a/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/types/error.rs +++ b/codegen/smithy-dafny-codegen/src/main/resources/templates/runtimes/rust/types/error.rs @@ -2,9 +2,10 @@ pub enum Error { $modeledErrorVariants:L CollectionOfErrors { - list: ::std::vec::Vec, + list: ::std::vec::Vec, message: ::std::string::String, }, + ValidationError(ValidationError), Opaque { obj: ::dafny_runtime::Object, }, @@ -14,8 +15,48 @@ impl ::std::cmp::Eq for Error {} impl ::std::fmt::Display for Error { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(f, "{:?}", self) + match self { + Self::ValidationError(err) => ::std::fmt::Display::fmt(err, f), + _ => ::std::fmt::Debug::fmt(self, f), + } } } -impl ::std::error::Error for Error {} +impl ::std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::ValidationError(err) => Some(err), + _ => None, + } + } +} + +impl Error { + pub fn wrap_validation_err(err: E) -> Self + where + E: ::std::error::Error + 'static, + { + Self::ValidationError(ValidationError(::std::rc::Rc::new(err))) + } +} + +#[derive(::std::clone::Clone, ::std::fmt::Debug)] +pub(crate) struct ValidationError(::std::rc::Rc); + +impl ::std::cmp::PartialEq for ValidationError { + fn eq(&self, other: &Self) -> bool { + ::std::rc::Rc::<(dyn std::error::Error + 'static)>::ptr_eq(&self.0, &other.0) + } +} + +impl ::std::fmt::Display for ValidationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + ::std::fmt::Display::fmt(&self.0, f) + } +} + +impl ::std::error::Error for ValidationError { + fn source(&self) -> ::std::option::Option<&(dyn ::std::error::Error + 'static)> { + ::std::option::Option::Some(self.0.as_ref()) + } +}