-
-
Notifications
You must be signed in to change notification settings - Fork 155
/
verify_accepts_format.cr
113 lines (94 loc) · 3.39 KB
/
verify_accepts_format.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Configure what types of formats your action responds to
module Lucky::VerifyAcceptsFormat
abstract def clients_desired_format : Symbol
macro included
before verify_accepted_format
def self._accepted_formats
[] of Symbol
end
end
# Set the single format that the Action accepts.
#
# Same as `accepted_formats` but this one only accepts one format and no
# default. If you pass an empty array or more than one format, you must
# use the other `accepted_formats` so you can tell Lucky what the `default`
# format should be.
#
# If something other than the accepted formats are requested, Lucky will raise
# a `Lucky::NotAcceptableError` error.
#
# ```
# # Default is set to :html since there is just one format
# accepted_formats [:html]
#
# # Raises at compile time because Lucky needs to know which format is the default
# accepted_formats [:html, :json]
#
# # If more than one format is accepted, you must provide the default explicitly
# accepted_formats [:html, :json], default: :html
# ```
macro accepted_formats(formats)
{% if !formats.is_a?(ArrayLiteral) %}
{% raise "#{@type} 'accepted_formats' should be an array of Symbols. Example: [:html, :json]" %}
{% end %}
{% if formats.size == 1 %}
accepted_formats {{ formats }}, default: {{ formats.first }}
{% else %}
{% formats.raise "#{@type} must pass a default to 'accepted_formats'. Example: accepted_formats [:html, :json], default: :html" %}
{% end %}
end
# Set what formats the Action accepts.
#
# If something other than the accepted formats are requested, Lucky will raise
# a `Lucky::NotAcceptableError` error.
#
# ```
# accepted_formats [:html, :json], default: :json
# ```
macro accepted_formats(formats, default)
{% if !formats.is_a?(ArrayLiteral) %}
{% formats.raise "#{@type} 'accepted_formats' should be an array of Symbols. Example: [:html, :json]" %}
{% end %}
{% if !default.is_a?(SymbolLiteral) %}
{% formats.raise "#{@type} default format should be a symbol. Example: :html" %}
{% end %}
def self._accepted_formats
{{ formats }}
end
default_format {{ default }}
end
private def verify_accepted_format
verify_all_formats_recognized!
if all_formats_allowed? || self.class._accepted_formats.includes?(clients_desired_format)
continue
else
raise Lucky::NotAcceptableError.new(
request: request,
action_name: self.class.name,
format: clients_desired_format,
accepted_formats: self.class._accepted_formats
)
end
end
private def verify_all_formats_recognized! : Nil
find_unrecognized_format.try do |unrecognized_format|
raise <<-TEXT
#{self.class.name} accepts an unrecognized format :#{unrecognized_format}
You can teach Lucky how to handle this format:
# Add this in config/mime_types.cr
Lucky::MimeType.register "text/custom", :#{unrecognized_format}
Or use one of these formats Lucky knows about:
#{Lucky::MimeType.known_formats.join(", ")}
TEXT
end
end
@_find_unrecognized_format : Symbol?
private def find_unrecognized_format : Symbol?
@_find_unrecognized_format ||= self.class._accepted_formats.find do |format|
!Lucky::MimeType.registered?(format)
end
end
private def all_formats_allowed? : Bool
self.class._accepted_formats.empty?
end
end