Description
Missing From
Implementation
Consider the following model:
service SampleService {
operations: [SampleOp]
}
@http(uri: "/sample", method: "POST")
operation SampleOp {
input := {
items: ItemMap
}
errors: [ValidationException]
}
@length(min: 0, max: 65535)
string ItemName
string ItemDescription
@length(min: 1, max: 100)
map ItemMap {
key: ItemName,
value: ItemListA
}
list ItemListA {
member: ItemListB
}
list ItemListB {
member: ItemDescription
}
An SDK generated with publicConstrainedTypes
set to false
does not compile and raises the following error:
error[E0277]: the trait bound `HashMap<std::string::String, Vec<Vec<std::string::String>>>: From<ItemMap>` is not satisfied
--> src/input.rs:136:55
This error occurs because SampleOpInput
is defined as a HashMap
with String
as the key:
pub struct SampleOpInput {
#[allow(missing_docs)] // documentation missing in model
pub items: ::std::option::Option<
::std::collections::HashMap<
::std::string::String,
::std::vec::Vec<::std::vec::Vec<::std::string::String>>,
>,
>,
}
The method build_enforcing_all_constraints
attempts to construct SampleOpInput
by invoking the From
implementation for ItemMap
. However, the generated implementation uses ItemName
(not String
) as the key type for the HashMap
:
impl ::std::convert::From<ItemMap>
for ::std::collections::HashMap<
crate::model::ItemName,
::std::vec::Vec<::std::vec::Vec<::std::string::String>>,
>
An additional From<ItemMap>
needs to be generated:
impl ::std::convert::From<ItemMap>
for ::std::collections::HashMap<
::std::string::String,
::std::vec::Vec<::std::vec::Vec<::std::string::String>>,
>
{
fn from(value: ItemMap) -> Self {
value
.into_inner()
.into_iter()
.map(|(k, v)| (k.into(), v))
.collect()
}
}
A directly constrained list with indirectly constrained map
Consider the following model:
operation SampleOp {
input := {
items: ItemList
}
}
@length(min: 1 max: 100)
list ItemList {
member: Item
}
map Item {
key: ItemName
value: ItemDescription
}
This results in non-compilable code:
93 | value.into_inner().into_iter().map(|v| v.into()).collect()
| ^^^^ the trait `From<HashMap<ItemName, std::string::String>>` is not implemented for `HashMap<std::string::String, std::string::String>`, which is required by `HashMap<ItemName, std::string::String>: Into<_>`
This happens because ItemList
is defined as:
pub(crate) struct ItemList(
pub(crate)
::std::vec::Vec<::std::collections::HashMap<crate::model::ItemName, ::std::string::String>>,
);
Where as the TryFrom
implementation assumes that the HashMap
has String
as key instead of ItemName
:
impl ::std::convert::From<ItemList>
for ::std::vec::Vec<::std::collections::HashMap<::std::string::String, ::std::string::String>>
{
fn from(value: ItemList) -> Self {
value.into_inner().into_iter().map(|v| v.into()).collect()
}
}
Constrained map with a non-constrained list that has a constrained list as member
@length(min: 1 max: 100)
map ItemMap {
key: ItemName,
value: ItemListA
}
list ItemListA {
member: ItemListB
}
@length(min: 1 max: 100)
list ItemListB {
member: ItemDescription
}
Results in a compilation error on v.into()
in the following From<ItemMap>
implementation:
impl ::std::convert::From<ItemMap>
for ::std::collections::HashMap<
::std::string::String,
::std::vec::Vec<::std::vec::Vec<::std::string::String>>,
>
{
fn from(value: ItemMap) -> Self {
value
.into_inner()
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect()
}
}
Nested lists
@length(min: 1 max: 100)
list ItemList {
member: ItemA
}
list ItemA {
member: ItemB
}
list ItemB {
member: ItemName
}
Results in an error in TryFrom<ItemsList>
implementation at v.into()
.
pub(crate) struct ItemList(
pub(crate) ::std::vec::Vec<::std::vec::Vec<::std::vec::Vec<crate::model::ItemName>>>,
);
impl ::std::convert::From<ItemList>
for ::std::vec::Vec<::std::vec::Vec<::std::vec::Vec<::std::string::String>>>
{
fn from(value: ItemList) -> Self {
value.into_inner().into_iter().map(|v| v.into()).collect()
}
}