-
Notifications
You must be signed in to change notification settings - Fork 2
/
time.cr
56 lines (50 loc) · 2.21 KB
/
time.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@[ADI::Register(tags: [{name: ATHR::Interface::TAG, priority: 105}])]
# Attempts to parse a date(time) string into a `::Time` instance.
#
# Optionally allows specifying the *format* and *location* to use when parsing the string via the `ATHR::Time::Format` annotation.
# If no *format* is specified, defaults to [RFC 3339](https://crystal-lang.org/api/Time.html#parse_rfc3339%28time:String%29-class-method).
# Defaults to `UTC` if no *location* is specified with the annotation.
#
# Raises an `ATH::Exceptions::BadRequest` if the date(time) string could not be parsed.
#
# TIP: The format can be anything supported via [Time::Format](https://crystal-lang.org/api/Time/Format.html).
#
# ```
# require "athena"
#
# class ExampleController < ATH::Controller
# @[ARTA::Get(path: "/event/{start_time}/{end_time}")]
# def event(
# @[ATHR::Time::Format("%F", location: Time::Location.load("Europe/Berlin"))]
# start_time : Time,
# end_time : Time
# ) : Nil
# start_time # => 2020-04-07 00:00:00.0 +02:00 Europe/Berlin
# end_time # => 2020-04-08 12:34:56.0 UTC
# end
# end
#
# ATH.run
#
# # GET /event/2020-04-07/2020-04-08T12:34:56Z
# ```
struct Athena::Framework::Controller::ValueResolvers::Time
include Athena::Framework::Controller::ValueResolvers::Interface
# Allows customing the time format and/or location used to parse the string datetime as part of the `ATHR::Time` resolver.
# See the related resolver documentation for more information.
configuration Format, format : String? = nil, location : ::Time::Location = ::Time::Location::UTC
# :inherit:
def resolve(request : ATH::Request, parameter : ATH::Controller::ParameterMetadata) : ::Time?
return unless parameter.instance_of? ::Time
if value = request.attributes.get? parameter.name, ::Time?
return value
end
return unless value = request.attributes.get? parameter.name, String?
if !(configuration = parameter.annotation_configurations[Format]?) || !(format = configuration.format)
return ::Time.parse_rfc3339(value)
end
::Time.parse value, format, configuration.location
rescue ex : ::Time::Format::Error
raise ATH::Exceptions::BadRequest.new "Invalid date(time) for parameter '#{parameter.name}'."
end
end