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

Generate types and type specs for all generated functions in aws-elixir and aws-erlang #107

Closed
Closed
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
1 change: 1 addition & 0 deletions lib/aws_codegen.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ defmodule AWS.CodeGen do
protocol: nil,
signature_version: nil,
service_id: nil,
shapes: %{},
signing_name: nil,
target_prefix: nil
end
Expand Down
55 changes: 54 additions & 1 deletion lib/aws_codegen/post_service.ex
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
defmodule AWS.CodeGen.PostService do
alias AWS.CodeGen.Docstring
alias AWS.CodeGen.Service
alias AWS.CodeGen.Shapes

Check warning on line 4 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.13.4, 25.0.4, 3.20.0)

unused alias Shapes

Check warning on line 4 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Shapes

Check warning on line 4 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Shapes

Check warning on line 4 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.13.4, 25.0.4, 3.20.0)

unused alias Shapes

Check warning on line 4 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Shapes

Check warning on line 4 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Shapes
alias AWS.CodeGen.Name

Check warning on line 5 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.13.4, 25.0.4, 3.20.0)

unused alias Name

Check warning on line 5 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name

Check warning on line 5 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name

Check warning on line 5 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.13.4, 25.0.4, 3.20.0)

unused alias Name

Check warning on line 5 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name

Check warning on line 5 in lib/aws_codegen/post_service.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name

defmodule Action do
defstruct arity: nil,
docstring: nil,
function_name: nil,
input: nil,
output: nil,
errors: %{},
host_prefix: nil,
name: nil
end

defmodule Shape do
defstruct name: nil,
type: nil,
members: [],
member: [],
enum: [],
min: nil,
required: [],
is_input: nil
end

@configuration %{
"ec2" => %{
content_type: "application/x-www-form-urlencoded",
Expand Down Expand Up @@ -57,6 +73,7 @@
service = spec.api["shapes"][spec.shape_name]
traits = service["traits"]
actions = collect_actions(language, spec.api)
shapes = collect_shapes(language, spec.api)
endpoint_prefix = traits["aws.api#service"]["endpointPrefix"] || traits["aws.api#service"]["arnNamespace"]
endpoint_info = endpoints_spec["services"][endpoint_prefix]
is_global = not is_nil(endpoint_info) and not Map.get(endpoint_info, "isRegionalized", true)
Expand Down Expand Up @@ -89,6 +106,7 @@
language: language,
module_name: spec.module_name,
protocol: protocol |> to_string() |> String.replace("_", "-"),
shapes: shapes,
signing_name: signing_name,
signature_version: AWS.CodeGen.Util.get_signature_version(service),
service_id: AWS.CodeGen.Util.get_service_id(service),
Expand Down Expand Up @@ -137,10 +155,45 @@
),
function_name: AWS.CodeGen.Name.to_snake_case(operation),
host_prefix: operation_spec["traits"]["smithy.api#endpoint"]["hostPrefix"],
name: String.replace(operation, ~r/com\.amazonaws\.[^#]+#/, "")
name: String.replace(operation, ~r/com\.amazonaws\.[^#]+#/, ""),
input: operation_spec["input"],
output: operation_spec["output"],
errors: operation_spec["errors"]
}
end)
|> Enum.sort(fn a, b -> a.function_name < b.function_name end)
|> Enum.uniq()
end

defp collect_shapes(_language, api_spec) do
api_spec["shapes"]
|> Enum.sort(fn {name_a, _}, {name_b, _} -> name_a < name_b end)
|> Enum.map(fn {name, shape} ->
{name,
%Shape{
name: name,
type: shape["type"],
member: shape["member"],
members: shape["members"],
min: shape["min"],
enum: shape["enum"],
is_input: is_input?(shape)
}}
end)
|> Enum.into(%{})
end

defp is_input?(shape) do
if Map.has_key?(shape, "traits") do
traits = shape["traits"]
if Map.has_key?(traits, "smithy.api#input") do
true
else
false
end
else
true
end
end

end
109 changes: 106 additions & 3 deletions lib/aws_codegen/rest_service.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ defmodule AWS.CodeGen.RestService do
send_body_as_binary?: false,
receive_body_as_binary?: false,
host_prefix: nil,
language: nil
language: nil,
input: nil,
output: nil,
errors: []

def method(action) do
result = action.method |> String.downcase() |> String.to_atom()
Expand Down Expand Up @@ -145,7 +148,8 @@ defmodule AWS.CodeGen.RestService do
signing_name: signing_name,
signature_version: AWS.CodeGen.Util.get_signature_version(service),
service_id: AWS.CodeGen.Util.get_service_id(service),
target_prefix: nil, ##TODO: metadata["targetPrefix"]
target_prefix: nil, ##TODO: metadata["targetPrefix"],
shapes: collect_shapes(language, spec.api)
}
end

Expand All @@ -157,6 +161,60 @@ defmodule AWS.CodeGen.RestService do
function_parameters(action, true)
end

def required_function_parameter_types(action) do
function_parameter_types(action, true)
end

def required_query_map_types(action) do
function_parameter_types(action, true)
end

def function_parameter_types(action, required_only \\ false) do
language = action.language
Enum.join([
join_parameter_types(action.url_parameters, language)
| case action.method do
"GET" ->
case required_only do
false ->
[
join_parameter_types(action.query_parameters, language),
join_parameter_types(action.request_header_parameters, language),
join_parameter_types(action.request_headers_parameters, language)
]

true ->
[
join_parameter_types(action.required_query_parameters, language),
join_parameter_types(action.required_request_header_parameters, language)
]
end

_ ->
[]
end
])
end

defp join_parameter_types(parameters, language) do
Enum.join(
Enum.map(
parameters,
fn parameter ->
if not parameter.required and language == :elixir do
", String.t() | nil"
else
if language == :elixir do
", String.t()"
else
", binary() | list()"
end
end
end
)
)
end

@doc """
Render function parameters, if any, in a way that can be inserted directly
into the code template. It can be asked to only return the required ones.
Expand Down Expand Up @@ -275,7 +333,10 @@ defmodule AWS.CodeGen.RestService do
send_body_as_binary?: Shapes.body_as_binary?(shapes, input_shape),
receive_body_as_binary?: Shapes.body_as_binary?(shapes, output_shape),
host_prefix: operation_spec["traits"]["smithy.api#endpoint"]["hostPrefix"],
language: language
language: language,
input: operation_spec["input"],
output: operation_spec["output"],
errors: operation_spec["errors"]
}
end)
|> Enum.sort(fn a, b -> a.function_name < b.function_name end)
Expand Down Expand Up @@ -363,4 +424,46 @@ defmodule AWS.CodeGen.RestService do
}
end

defmodule Shape do
defstruct name: nil,
type: nil,
members: [],
member: [],
enum: [],
min: nil,
required: [],
is_input: nil
end

defp collect_shapes(_language, api_spec) do
api_spec["shapes"]
|> Enum.sort(fn {name_a, _}, {name_b, _} -> name_a < name_b end)
|> Enum.map(fn {name, shape} ->
{name,
%Shape{
name: name,
type: shape["type"],
member: shape["member"],
members: shape["members"],
min: shape["min"],
enum: shape["enum"],
is_input: is_input?(shape)
}}
end)
|> Enum.into(%{})
end

defp is_input?(shape) do
if Map.has_key?(shape, "traits") do
traits = shape["traits"]
if Map.has_key?(traits, "smithy.api#input") do
true
else
false
end
else
true
end
end

end
1 change: 1 addition & 0 deletions lib/aws_codegen/shapes.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
defmodule AWS.CodeGen.Shapes do
alias AWS.CodeGen.Name

Check warning on line 2 in lib/aws_codegen/shapes.ex

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.13.4, 25.0.4, 3.20.0)

unused alias Name

Check warning on line 2 in lib/aws_codegen/shapes.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name

Check warning on line 2 in lib/aws_codegen/shapes.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name

Check warning on line 2 in lib/aws_codegen/shapes.ex

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest, 1.13.4, 25.0.4, 3.20.0)

unused alias Name

Check warning on line 2 in lib/aws_codegen/shapes.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name

Check warning on line 2 in lib/aws_codegen/shapes.ex

View workflow job for this annotation

GitHub Actions / Elixir 1.13.4 / OTP 25.0.4

unused alias Name
@moduledoc false

def get_input_shape(operation_spec) do
Expand Down
Loading
Loading