Skip to content

Commit

Permalink
Change properties key to _properties_ to reduce chance of conflict (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
maxpowa authored and RX14 committed Oct 26, 2017
1 parent 4b75571 commit 4d587a3
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 12 deletions.
14 changes: 14 additions & 0 deletions spec/std/json/mapping_spec.cr
Expand Up @@ -55,6 +55,12 @@ private class JSONWithNilableTimeEmittingNull
end
end

private class JSONWithPropertiesKey
JSON.mapping(
properties: Hash(String, String),
)
end

private class JSONWithSimpleMapping
JSON.mapping({name: String, age: Int32})
end
Expand Down Expand Up @@ -252,6 +258,14 @@ describe "JSON mapping" do
json.to_json.should eq(%({"value":null}))
end

it "outputs JSON with properties key" do
input = {
properties: {"foo" => "bar"},
}.to_json
json = JSONWithPropertiesKey.from_json(input)
json.to_json.should eq(input)
end

it "parses json with keywords" do
json = JSONWithKeywordsMapping.from_json(%({"end": 1, "abstract": 2}))
json.end.should eq(1)
Expand Down
24 changes: 12 additions & 12 deletions src/json/mapping.cr
Expand Up @@ -60,12 +60,12 @@ module JSON
# If *strict* is `true`, unknown properties in the JSON
# document will raise a parse exception. The default is `false`, so unknown properties
# are silently ignored.
macro mapping(properties, strict = false)
{% for key, value in properties %}
{% properties[key] = {type: value} unless value.is_a?(HashLiteral) || value.is_a?(NamedTupleLiteral) %}
macro mapping(_properties_, strict = false)
{% for key, value in _properties_ %}
{% _properties_[key] = {type: value} unless value.is_a?(HashLiteral) || value.is_a?(NamedTupleLiteral) %}
{% end %}

{% for key, value in properties %}
{% for key, value in _properties_ %}
@{{key.id}} : {{value[:type]}} {{ (value[:nilable] ? "?" : "").id }}

{% if value[:setter] == nil ? true : value[:setter] %}
Expand All @@ -90,7 +90,7 @@ module JSON
{% end %}

def initialize(%pull : ::JSON::PullParser)
{% for key, value in properties %}
{% for key, value in _properties_ %}
%var{key.id} = nil
%found{key.id} = false
{% end %}
Expand All @@ -101,7 +101,7 @@ module JSON
%key_location = %pull.location
key = %pull.read_object_key
case key
{% for key, value in properties %}
{% for key, value in _properties_ %}
when {{value[:key] || key.id.stringify}}
%found{key.id} = true

Expand Down Expand Up @@ -137,15 +137,15 @@ module JSON
end
%pull.read_next

{% for key, value in properties %}
{% for key, value in _properties_ %}
{% unless value[:nilable] || value[:default] != nil %}
if %var{key.id}.nil? && !%found{key.id} && !::Union({{value[:type]}}).nilable?
raise ::JSON::ParseException.new("Missing json attribute: {{(value[:key] || key).id}}", *%location)
end
{% end %}
{% end %}

{% for key, value in properties %}
{% for key, value in _properties_ %}
{% if value[:nilable] %}
{% if value[:default] != nil %}
@{{key.id}} = %found{key.id} ? %var{key.id} : {{value[:default]}}
Expand All @@ -159,7 +159,7 @@ module JSON
{% end %}
{% end %}

{% for key, value in properties %}
{% for key, value in _properties_ %}
{% if value[:presence] %}
@{{key.id}}_present = %found{key.id}
{% end %}
Expand All @@ -168,7 +168,7 @@ module JSON

def to_json(json : ::JSON::Builder)
json.object do
{% for key, value in properties %}
{% for key, value in _properties_ %}
_{{key.id}} = @{{key.id}}

{% unless value[:emit_null] %}
Expand Down Expand Up @@ -216,7 +216,7 @@ module JSON

# This is a convenience method to allow invoking `JSON.mapping`
# with named arguments instead of with a hash/named-tuple literal.
macro mapping(**properties)
::JSON.mapping({{properties}})
macro mapping(**_properties_)
::JSON.mapping({{_properties_}})
end
end

0 comments on commit 4d587a3

Please sign in to comment.