Skip to content

Commit

Permalink
json_mapping and yaml_mapping are now JSON.mapping and `YAML.ma…
Browse files Browse the repository at this point in the history
…pping`
  • Loading branch information
Ary Borenszweig committed Oct 16, 2015
1 parent 25d608d commit be93828
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 156 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* **(breaking change)** The `CGI` module's funcionality has been moved to `URI` and `HTTP::Params`
* **(breaking change)** `IO#read()` is now `IO#gets_to_end`. Removed `IO#read(count)`, added `IO#skip(count)`
* **(breaking change)** `json_mapping` is now `JSON.mapping`. `yaml_mapping` is now `YAML.mapping`.
* Added `crystal tool format` that automatically formats your code
* `protected` methods can now be invoked between types inside a same namespace
* Removed `curses`, you can use `https://github.com/jreinert/ncurses-crystal`
Expand Down
22 changes: 11 additions & 11 deletions spec/std/json/mapping_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ require "spec"
require "json"

class JSONPerson
json_mapping({
JSON.mapping({
name: {type: String},
age: {type: Int32, nilable: true},
})
Expand All @@ -14,33 +14,33 @@ class JSONPerson
end

class StrictJSONPerson
json_mapping({
JSON.mapping({
name: {type: String},
age: {type: Int32, nilable: true},
}, true)
end

class JSONPersonEmittingNull
json_mapping({
JSON.mapping({
name: {type: String},
age: {type: Int32, nilable: true, emit_null: true},
})
end

class JSONWithBool
json_mapping({
JSON.mapping({
value: {type: Bool},
})
end

class JSONWithTime
json_mapping({
JSON.mapping({
value: {type: Time, converter: Time::Format.new("%F %T")},
})
end

class JSONWithNilableTime
json_mapping({
JSON.mapping({
value: {type: Time, converter: Time::Format.new("%F")},
})

Expand All @@ -49,7 +49,7 @@ class JSONWithNilableTime
end

class JSONWithNilableTimeEmittingNull
json_mapping({
JSON.mapping({
value: {type: Time, converter: Time::Format.new("%F"), emit_null: true},
})

Expand All @@ -58,19 +58,19 @@ class JSONWithNilableTimeEmittingNull
end

class JSONWithSimpleMapping
json_mapping({name: String, age: Int32})
JSON.mapping({name: String, age: Int32})
end

class JSONWithKeywordsMapping
json_mapping({end: Int32, abstract: Int32})
JSON.mapping({end: Int32, abstract: Int32})
end

class JSONWithAny
json_mapping({name: String, any: JSON::Any})
JSON.mapping({name: String, any: JSON::Any})
end

class JsonWithProblematicKeys
json_mapping({
JSON.mapping({
key: Int32,
pull: Int32,
})
Expand Down
10 changes: 5 additions & 5 deletions spec/std/yaml/mapping_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ require "spec"
require "yaml"

class YAMLPerson
yaml_mapping({
YAML.mapping({
name: String,
age: {type: Int32, nilable: true},
})
Expand All @@ -14,26 +14,26 @@ class YAMLPerson
end

class StrictYAMLPerson
yaml_mapping({
YAML.mapping({
name: {type: String},
age: {type: Int32, nilable: true},
}, true)
end

class YAMLWithBool
yaml_mapping({
YAML.mapping({
value: {type: Bool},
})
end

class YAMLWithTime
yaml_mapping({
YAML.mapping({
value: {type: Time, converter: Time::Format.new("%F %T")},
})
end

class YAMLWithKey
yaml_mapping({
YAML.mapping({
key: String,
value: Int32,
pull: Int32,
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/tools/context.cr
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module Crystal
end

class ContextResult
json_mapping({
JSON.mapping({
status: {type: String},
message: {type: String},
contexts: {type: Array(HashStringType), nilable: true},
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/crystal/tools/implementations.cr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ require "json"

module Crystal
class ImplementationResult
json_mapping({
JSON.mapping({
status: {type: String},
message: {type: String},
implementations: {type: Array(ImplementationTrace), nilable: true},
Expand Down Expand Up @@ -32,7 +32,7 @@ module Crystal
# It keeps track of macro expansion in a human friendly way and
# pointing to the exact line an expansion and method definition occurs.
class ImplementationTrace
json_mapping({
JSON.mapping({
line: {type: Int32},
column: {type: Int32},
filename: {type: String},
Expand Down
2 changes: 1 addition & 1 deletion src/json/any.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# You can use `JSON::Any` inside a `JSON::Mapping` to make a property be parsed
# You can use `JSON::Any` inside a `JSON#mapping` to make a property be parsed
# to a `JSON::Type`. This is useful if you have properties with dynamic content
# that must later be inspected at runtime.
module JSON::Any
Expand Down
6 changes: 3 additions & 3 deletions src/json/json.cr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# The JSON module allows parsing and generating [JSON](http://json.org/) documents.
#
# ### Parsing and generating with `JSON::Mapping`
# ### Parsing and generating with `JSON#mapping`
#
# Use `JSON::Mapping` to define how an object is mapped to JSON, making it
# Use `JSON#mapping` to define how an object is mapped to JSON, making it
# the recommended easy, type-safe and efficient option for parsing and generating
# JSON. Refer to that module's documentation to learn about it.
#
Expand Down Expand Up @@ -32,7 +32,7 @@
#
# `to_json` and `to_json(IO)` methods are provided for primitive types, but you
# need to define `to_json(IO)` for custom objects, either manually or using
# `JSON::Mapping`.
# `JSON#mapping`.
module JSON
# Exception thrown on a JSON parse error.
class ParseException < Exception
Expand Down
114 changes: 54 additions & 60 deletions src/json/mapping.cr
Original file line number Diff line number Diff line change
@@ -1,61 +1,59 @@
# The `JSON::Mapping` module defines a single macro, `json_mapping`, that
# defines how an object is mapped to JSON.
#
# This module is automatically included by `Object` when you `require "json"`.
#
# ### Example
#
# ```
# require "json"
#
# class Location
# json_mapping({
# lat: Float64,
# lng: Float64,
# })
# end
#
# class House
# json_mapping({
# address: String,
# location: {type: Location, nilable: true},
# })
# end
#
# house = House.from_json(%({"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}))
# house.address #=> "Crystal Road 1234"
# house.location #=> #&lt;Location:0x10cd93d80 @lat=12.3, @lng=34.5>
# house.to_json #=> %({"address":"Crystal Road 1234","location":{"lat":12.3,"lng":34.5}})
# ```
#
# ### Usage
#
# `json_mapping` must receive a hash literal whose keys will define Crystal properties.
#
# The value of each key can be a single type (not a union type). Primitive types (numbers, string, boolean and nil)
# are supported, as well as custom objects which use `json_mapping` or define a `new` method
# that accepts a `JSON::PullParser` and returns an object from it.
#
# The value can also be another hash literal with the following options:
# * type: (required) the single type described above
# * key: the property name in the JSON document (as opposed to the property name in the Crystal code)
# * nilable: if true, the property can be `Nil`
# * emit_null: if true, emits a `null` value for nilable properties (by default nulls are not emitted)
# * converter: specify an alternate type for parsing and generation. The converter must define `from_json(JSON::PullParser)` and `to_json(value, IO)` as class methods.
#
# The mapping also automatically defines Crystal properties (getters and setters) for each
# of the keys. It doesn't define a constructor accepting those arguments, but you can provide
# an overload.
#
# The macro basically defines a constructor accepting a `JSON::PullParser` that reads from
# it and initializes this type's instance variables. It also defines a `to_json(IO)` method
# by invoking `to_json(IO)` on each of the properties (unless a converter is specified, in
# which case `to_json(value, IO)` is invoked).
module JSON::Mapping
# Defines a JSON mapping. If `strict` is true, unknown properties in the JSON
module JSON
# The `JSON.mapping` macro defines how an object is mapped to JSON.
#
# ### Example
#
# ```
# require "json"
#
# class Location
# JSON.mapping({
# lat: Float64,
# lng: Float64,
# })
# end
#
# class House
# JSON.mapping({
# address: String,
# location: {type: Location, nilable: true},
# })
# end
#
# house = House.from_json(%({"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}))
# house.address #=> "Crystal Road 1234"
# house.location #=> #&lt;Location:0x10cd93d80 @lat=12.3, @lng=34.5>
# house.to_json #=> %({"address":"Crystal Road 1234","location":{"lat":12.3,"lng":34.5}})
# ```
#
# ### Usage
#
# `JSON.mapping` must receive a hash literal whose keys will define Crystal properties.
#
# The value of each key can be a single type (not a union type). Primitive types (numbers, string, boolean and nil)
# are supported, as well as custom objects which use `JSON.mapping` or define a `new` method
# that accepts a `JSON::PullParser` and returns an object from it.
#
# The value can also be another hash literal with the following options:
# * type: (required) the single type described above
# * key: the property name in the JSON document (as opposed to the property name in the Crystal code)
# * nilable: if true, the property can be `Nil`
# * emit_null: if true, emits a `null` value for nilable properties (by default nulls are not emitted)
# * converter: specify an alternate type for parsing and generation. The converter must define `from_json(JSON::PullParser)` and `to_json(value, IO)` as class methods.
#
# The mapping also automatically defines Crystal properties (getters and setters) for each
# of the keys. It doesn't define a constructor accepting those arguments, but you can provide
# an overload.
#
# The macro basically defines a constructor accepting a `JSON::PullParser` that reads from
# it and initializes this type's instance variables. It also defines a `to_json(IO)` method
# by invoking `to_json(IO)` on each of the properties (unless a converter is specified, in
# which case `to_json(value, IO)` is invoked).
#
# 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 json_mapping(properties, strict = false)
macro mapping(properties, strict = false)
{% for key, value in properties %}
{% properties[key] = {type: value} unless value.is_a?(HashLiteral) %}
{% end %}
Expand Down Expand Up @@ -141,7 +139,3 @@ module JSON::Mapping
end
end
end

class Object
include JSON::Mapping
end
Loading

0 comments on commit be93828

Please sign in to comment.