Skip to content

Commit

Permalink
Use FeatureSet struct
Browse files Browse the repository at this point in the history
  • Loading branch information
omus committed Sep 25, 2021
1 parent cccc439 commit e170fbc
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 90 deletions.
27 changes: 14 additions & 13 deletions src/AWS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export sign!, sign_aws2!, sign_aws4!
export JSONService, RestJSONService, RestXMLService, QueryService, set_features

const DEFAULT_REGION = "us-east-1"
const DEFAULT_SERVICE_FEATURES = NamedTuple()

include(joinpath("utilities", "utilities.jl"))

Expand All @@ -42,6 +41,8 @@ using ..AWSExceptions: AWSException
const user_agent = Ref("AWS.jl/1.0.0")
const aws_config = Ref{AbstractAWSConfig}()

Base.@kwdef struct FeatureSet end

"""
global_aws_config()
Expand Down Expand Up @@ -125,10 +126,11 @@ using AWS: @service
"""
macro service(module_name::Symbol, features...)
service_name = joinpath(@__DIR__, "services", lowercase(string(module_name)) * ".jl")
service_features = _process_service_features(features, DEFAULT_SERVICE_FEATURES)
map(_assignment_to_kw!, features)

module_block = quote
const SERVICE_FEATURES = $service_features
using AWS: FeatureSet
const SERVICE_FEATURE_SET = FeatureSet(; $(features...))
include($service_name)
end

Expand Down Expand Up @@ -174,12 +176,11 @@ end

struct ServiceWrapper{S<:Service}
service::S
features::NamedTuple
feature_set::FeatureSet
end

function set_features(service::Service; features...)
features = merge(DEFAULT_SERVICE_FEATURES, features)
return ServiceWrapper(service, features)
return ServiceWrapper(service, FeatureSet(; features...))
end

# Needs to be included after the definition of struct otherwise it cannot find them
Expand Down Expand Up @@ -224,7 +225,7 @@ function (service::RestXMLService)(
request_uri::String,
args::AbstractDict{String,<:Any}=Dict{String,Any}();
aws_config::AbstractAWSConfig=global_aws_config(),
features::NamedTuple=DEFAULT_SERVICE_FEATURES,
feature_set::FeatureSet=FeatureSet(),
)
return_headers = _pop!(args, "return_headers", false)

Expand Down Expand Up @@ -277,7 +278,7 @@ function (service::QueryService)(
operation::String,
args::AbstractDict{String,<:Any}=Dict{String,Any}();
aws_config::AbstractAWSConfig=global_aws_config(),
features::NamedTuple=DEFAULT_SERVICE_FEATURES,
feature_set::FeatureSet=FeatureSet(),
)
POST_RESOURCE = "/"
return_headers = _pop!(args, "return_headers", false)
Expand Down Expand Up @@ -320,7 +321,7 @@ function (service::JSONService)(
operation::String,
args::AbstractDict{String,<:Any}=Dict{String,Any}();
aws_config::AbstractAWSConfig=global_aws_config(),
features::NamedTuple=DEFAULT_SERVICE_FEATURES,
feature_set::FeatureSet=FeatureSet(),
)
POST_RESOURCE = "/"
return_headers = _pop!(args, "return_headers", false)
Expand Down Expand Up @@ -363,7 +364,7 @@ function (service::RestJSONService)(
request_uri::String,
args::AbstractDict{String,<:Any}=Dict{String,String}();
aws_config::AbstractAWSConfig=global_aws_config(),
features::NamedTuple=DEFAULT_SERVICE_FEATURES,
feature_set::FeatureSet=FeatureSet(),
)
return_headers = _pop!(args, "return_headers", false)

Expand All @@ -387,9 +388,9 @@ function (service::RestJSONService)(
return submit_request(aws_config, request; return_headers=return_headers)
end

function (service::ServiceWrapper)(args...; features::NamedTuple=NamedTuple(), kwargs...)
features = merge(service.features, features)
return service.service(args...; features=features, kwargs...)
function (service::ServiceWrapper)(args...; feature_set=nothing, kwargs...)
feature_set = something(feature_set, service.feature_set)
return service.service(args...; feature_set=feature_set, kwargs...)
end

function __init__()
Expand Down
36 changes: 18 additions & 18 deletions src/api_generation/high_level.jl
Original file line number Diff line number Diff line change
Expand Up @@ -144,28 +144,28 @@ function _generate_high_level_definition(

if required_keys && (idempotent || headers)
return """
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", $params_headers_str; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", Dict{String, Any}(mergewith(_merge, $params_headers_str, params)); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", $params_headers_str; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", Dict{String, Any}(mergewith(_merge, $params_headers_str, params)); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
elseif !required_keys && (idempotent || headers)
return """
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", $params_headers_str; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", Dict{String, Any}(mergewith(_merge, $params_headers_str, params)); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", $params_headers_str; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", Dict{String, Any}(mergewith(_merge, $params_headers_str, params)); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
elseif required_keys && !isempty(req_kv)
return """
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", $req_str); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", Dict{String, Any}(mergewith(_merge, $req_str), params)); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", $req_str); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", Dict{String, Any}(mergewith(_merge, $req_str), params)); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
elseif required_keys
return """
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\"; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", params; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
else
return """
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\"; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", params; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$method\", \"$request_uri\", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
end
end
Expand Down Expand Up @@ -193,23 +193,23 @@ function _generate_high_level_definition(

if required && idempotent
return """
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}($(join(req_kv, ", ")), $(join(idempotent_kv, ", "))); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}(mergewith(_merge, Dict{String, Any}($(join(req_kv, ", ")), $(join(idempotent_kv, ", "))), params)); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}($(join(req_kv, ", ")), $(join(idempotent_kv, ", "))); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}(mergewith(_merge, Dict{String, Any}($(join(req_kv, ", ")), $(join(idempotent_kv, ", "))), params)); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
elseif required
return """
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}($(join(req_kv, ", "))); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}(mergewith(_merge, Dict{String, Any}($(join(req_kv, ", "))), params)); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name($(join(req_keys, ", ")); aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}($(join(req_kv, ", "))); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name($(join(req_keys, ", ")), params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}(mergewith(_merge, Dict{String, Any}($(join(req_kv, ", "))), params)); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
elseif idempotent
return """
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}($(join(idempotent_kv, ", "))); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}(mergewith(_merge, Dict{String, Any}($(join(idempotent_kv, ", "))), params)); aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}($(join(idempotent_kv, ", "))); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", Dict{String, Any}(mergewith(_merge, Dict{String, Any}($(join(idempotent_kv, ", "))), params)); aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
else
return """
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\"; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", params; aws_config=aws_config, features=SERVICE_FEATURES)
$formatted_function_name(; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
$formatted_function_name(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = $service_name(\"$function_name\", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET)
"""
end
end
Expand Down
33 changes: 9 additions & 24 deletions src/utilities/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,31 +104,16 @@ function _generate_rest_resource(request_uri::String, args::AbstractDict{String,
return request_uri
end

# Take a list of user defined features, `key=value` expressions, and verifies that all of
# the keys are defined within `defaults`. If any key is not defined by the user then the
# value from `defaults` will be used. Returns a `NamedTuple` expression.
function _process_service_features(args, defaults)
feature_dict = Dict{Symbol,Any}(pairs(defaults))
for ex in args
if ex isa Expr && ex.head === :(=)
k, v = ex.args[1:2]
if haskey(feature_dict, k)
feature_dict[k] = v
else
throw(ArgumentError("Unsupported feature `$ex` specified"))
end
else
throw(ArgumentError("Expected feature, instead found: `$ex`"))
end
end

# Turn the feature dictionary into a `NamedTuple` expression. Note: Julia 1.4 and below
# do not support `:((;))`.
nt = if !isempty(feature_dict)
Expr(:tuple, Expr(:parameters, [Expr(:kw, p...) for p in feature_dict]...))
function _assignment_to_kw!(expr::Expr)
if expr.head === :(=)
expr.head = :kw
else
:(NamedTuple())
throw(ArgumentError("Expected assignment expression, instead found: `$expr`"))
end

return nt
return expr
end

function _assignment_to_kw!(x)
throw(ArgumentError("Expected assignment expression, instead found: `$x`"))
end
Loading

0 comments on commit e170fbc

Please sign in to comment.