Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make enum trait a list of structures #326

Merged
merged 1 commit into from
Mar 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions docs/source/spec/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3322,18 +3322,12 @@ Summary
Trait selector
``string``
Value type
``map`` of enum constant values to structures optionally containing a name,
documentation, tags, and/or a deprecation flag.
``list`` of enum definition structures.

Smithy models SHOULD apply the enum trait when string shapes have a fixed
set of allowable values.

The enum trait is a map of allowed string values to enum constant definition
structures. Enum values do not allow aliasing; all enum constant values MUST be
unique across the entire set.

An enum definition is a structure that supports the following optional
members:
An enum definition is a structure that supports the following members:

.. list-table::
:header-rows: 1
Expand All @@ -3342,6 +3336,10 @@ members:
* - Property
- Type
- Description
* - value
- string
- **Required**. Defines the enum value that is sent over the wire.
Values MUST be unique across all enum definitions in an ``enum`` trait.
* - name
- string
- Defines a constant name to use when referencing an enum value.
Expand All @@ -3358,6 +3356,8 @@ members:
(``a-z``) and SHOULD NOT start with an ASCII underscore (``_``). That
is, enum names SHOULD match the following regular expression:
``^[A-Z]+[A-Z_0-9]*$``.

Names MUST be unique across all enum definitions in an ``enum`` trait.
* - documentation
- string
- Defines documentation about the enum value in the CommonMark_ format.
Expand All @@ -3384,8 +3384,9 @@ The following example defines an enum of valid string values for ``MyString``.

.. code-tab:: smithy

@enum(
t2.nano: {
@enum([
{
value: "t2.nano",
name: "T2_NANO",
documentation: """
T2 instances are Burstable Performance
Expand All @@ -3394,7 +3395,8 @@ The following example defines an enum of valid string values for ``MyString``.
baseline.""",
tags: ["ebsOnly"]
},
t2.micro: {
{
value: "t2.micro",
name: "T2_MICRO",
documentation: """
T2 instances are Burstable Performance
Expand All @@ -3403,11 +3405,12 @@ The following example defines an enum of valid string values for ``MyString``.
baseline.""",
tags: ["ebsOnly"]
},
m256.mega: {
{
value: "m256.mega",
name: "M256_MEGA",
deprecated: true
}
)
])
string MyString

.. code-tab:: json
Expand All @@ -3418,26 +3421,29 @@ The following example defines an enum of valid string values for ``MyString``.
"smithy.example#MyString": {
"type": "string",
"traits": {
"smithy.api#enum": {
"t2.nano": {
"smithy.api#enum": [
{
"value": "t2.nano",
"name": "T2_NANO",
"documentation": "T2 instances are ...",
"tags": [
"ebsOnly"
]
},
"t2.micro": {
{
"value": "t2.micro",
"name": "T2_MICRO",
"documentation": "T2 instances are ...",
"tags": [
"ebsOnly"
]
},
"m256.mega": {
{
"value": "m256.mega",
"name": "M256_MEGA",
"deprecated": true
}
}
]
}
}
}
Expand Down Expand Up @@ -5022,7 +5028,7 @@ can also support configuration settings.
}

@private
@enum("SHA-2": {})
@enum([{value": "SHA-2"}])
string AlgorithmAuthAlgorithm

@algorithmAuth(algorithm: "SHA-2")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,16 @@
"example.smithy#EnumString": {
"type": "string",
"traits": {
"smithy.api#enum": {
"a": {
"smithy.api#enum": [
{
"value": "a",
"name": "A"
},
"c": {
{
"value": "c",
"name": "C"
}
}
]
}
},
"example.smithy#PayloadDescriptions": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,24 @@
"aws.apigateway#IntegrationType": {
"type": "string",
"traits": {
"smithy.api#enum": {
"aws": {
"smithy.api#enum": [
{
"value": "aws",
"name": "AWS"
},
"aws_proxy": {
{
"value": "aws_proxy",
"name": "AWS_PROXY"
},
"http": {
{
"value": "http",
"name": "HTTP"
},
"http_proxy": {
{
"value": "http_proxy",
"name": "HTTP_PROXY"
}
}
]
}
},
"aws.apigateway#IamRoleArn": {
Expand Down Expand Up @@ -283,42 +287,41 @@
"type": "string",
"traits": {
"smithy.api#private": true,
"smithy.api#enum": {
"INTERNET": {},
"VPC_LINK": {}
}
"smithy.api#enum": [
{"value": "INTERNET"},
{"value": "VPC_LINK"}
]
}
},
"aws.apigateway#PassThroughBehavior": {
"type": "string",
"traits": {
"smithy.api#documentation": "Defines the passThroughBehavior for the integration",
"smithy.api#enum": {
"when_no_templates": {
"smithy.api#enum": [
{
"value": "when_no_templates",
"name": "WHEN_NO_TEMPLATES"
},
"when_no_match": {
{
"value": "when_no_match",
"name": "WHEN_NO_MATCH"
},
"never": {
{
"value": "never",
"name": "NEVER"
}
},
],
"smithy.api#private": true
}
},
"aws.apigateway#ContentHandling": {
"type": "string",
"traits": {
"smithy.api#documentation": "Defines the contentHandling for the integration",
"smithy.api#enum": {
"CONVERT_TO_TEXT": {
"name": "CONVERT_TO_TEXT"
},
"CONVERT_TO_BINARY": {
"name": "CONVERT_TO_BINARY"
}
},
"smithy.api#enum": [
{"value": "CONVERT_TO_TEXT", "name": "CONVERT_TO_TEXT"},
{"value": "CONVERT_TO_BINARY", "name": "CONVERT_TO_BINARY"}
],
"smithy.api#private": true
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,22 +90,22 @@
"traits": {
"smithy.api#private": true,
"smithy.api#documentation": "The IAM policy type of the value that will supplied for this context key",
"smithy.api#enum": {
"ARN": {},
"ArrayOfARN": {},
"Binary": {},
"ArrayOfBinary": {},
"String": {},
"ArrayOfString": {},
"Numeric": {},
"ArrayOfNumeric": {},
"Date": {},
"ArrayOfDate": {},
"Bool": {},
"ArrayOfBool": {},
"IPAddress": {},
"ArrayOfIPAddress": {}
}
"smithy.api#enum": [
{"value": "ARN"},
{"value": "ArrayOfARN"},
{"value": "Binary"},
{"value": "ArrayOfBinary"},
{"value": "String"},
{"value": "ArrayOfString"},
{"value": "Numeric"},
{"value": "ArrayOfNumeric"},
{"value": "Date"},
{"value": "ArrayOfDate"},
{"value": "Bool"},
{"value": "ArrayOfBool"},
{"value": "IPAddress"},
{"value": "ArrayOfIPAddress"}
]
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions smithy-aws-protocol-tests/model/shared-types.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ list TimestampList {
member: Timestamp,
}

@enum(
Foo: {},
Baz: {},
Bar: {},
"1": {},
"0": {},
)
@enum([
{value: "Foo"},
{value: "Baz"},
{value: "Bar"},
{value: "1"},
{value: "0"},
])
string FooEnum

list FooEnumList {
Expand Down
19 changes: 12 additions & 7 deletions smithy-aws-traits/src/main/resources/META-INF/smithy/aws.api.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,28 +79,33 @@
"smithy.api#trait": {
"selector": ":test(simpleType, collection, structure, union, member)"
},
"smithy.api#enum": {
"content": {
"smithy.api#enum": [
{
"value": "content",
"name": "CUSTOMER_CONTENT",
"documentation": "Customer content means any software (including machine images), data, text, audio, video or images that customers or any customer end user transfers to AWS for processing, storage or hosting by AWS services in connection with the customer\u2019s accounts and any computational results that customers or any customer end user derive from the foregoing through their use of AWS services."
},
"account": {
{
"value": "account",
"name": "CUSTOMER_ACCOUNT_INFORMATION",
"documentation": "Account information means information about customers that customers provide to AWS in connection with the creation or administration of customers\u2019 accounts."
},
"usage": {
{
"value": "usage",
"name": "SERVICE_ATTRIBUTES",
"documentation": "Service Attributes means service usage data related to a customer\u2019s account, such as resource identifiers, metadata tags, security and access roles, rules, usage policies, permissions, usage statistics, logging data, and analytics."
},
"tagging": {
{
"value": "tagging",
"name": "TAG_DATA",
"documentation": "Designates metadata tags applied to AWS resources."
},
"permissions": {
{
"value": "permissions",
"name": "PERMISSIONS_DATA",
"documentation": "Designates security and access roles, rules, usage policies, and permissions."
}
},
],
"smithy.api#documentation": "Designates the target as containing data of a known classification level."
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import software.amazon.smithy.diff.ChangedShape;
import software.amazon.smithy.diff.Differences;
import software.amazon.smithy.model.shapes.Shape;
import software.amazon.smithy.model.traits.EnumConstantBody;
import software.amazon.smithy.model.traits.EnumDefinition;
import software.amazon.smithy.model.traits.EnumTrait;
import software.amazon.smithy.model.validation.ValidationEvent;
import software.amazon.smithy.utils.OptionalUtils;
Expand All @@ -46,26 +47,32 @@ private List<ValidationEvent> validateEnum(ChangedShape<Shape> change, Pair<Enum
EnumTrait newTrait = trait.getRight();
List<ValidationEvent> events = new ArrayList<>();

oldTrait.getValues().forEach((key, value) -> {
if (!newTrait.getValues().containsKey(key)) {
events.add(error(change.getNewShape(), String.format("Enum value `%s` was removed", key)));
for (EnumDefinition definition : oldTrait.getValues()) {
Optional<EnumDefinition> maybeNewValue = newTrait.getValues().stream()
.filter(d -> d.getValue().equals(definition.getValue()))
.findFirst();

if (!maybeNewValue.isPresent()) {
events.add(error(change.getNewShape(), String.format(
"Enum value `%s` was removed", definition.getValue())));
} else {
EnumConstantBody newValue = newTrait.getValues().get(key);
if (!newValue.getName().equals(value.getName())) {
EnumDefinition newValue = maybeNewValue.get();
if (!newValue.getName().equals(definition.getName())) {
events.add(error(change.getNewShape(), String.format(
"Enum `name` changed from `%s` to `%s` for the `%s` value",
value.getName().orElse(null),
definition.getName().orElse(null),
newValue.getName().orElse(null),
key)));
definition.getValue())));
}
}
});
}

newTrait.getValues().forEach((key, value) -> {
if (!oldTrait.getValues().containsKey(key)) {
events.add(note(change.getNewShape(), String.format("Enum value `%s` was added", key)));
for (EnumDefinition definition : newTrait.getValues()) {
if (!oldTrait.getEnumDefinitionValues().contains(definition.getValue())) {
events.add(note(change.getNewShape(), String.format(
"Enum value `%s` was added", definition.getValue())));
}
});
}

return events;
}
Expand Down
Loading