From 2886c207e04d4230c0c5478becbfd367ea157cd4 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Mon, 6 Mar 2017 12:18:04 -0300 Subject: [PATCH] Add support for nillables with `T | Nil` syntax. --- spec/mapping_spec.cr | 9 +++++++++ src/db/mapping.cr | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/spec/mapping_spec.cr b/spec/mapping_spec.cr index 2969e07..de89376 100644 --- a/spec/mapping_spec.cr +++ b/spec/mapping_spec.cr @@ -36,6 +36,13 @@ class MappingWithNilTypes }) end +class MappingWithNilUnionTypes + DB.mapping({ + c0: {type: Int32 | Nil, default: 10}, + c1: Nil | String, + }) +end + class MappingWithKeys DB.mapping({ foo: {type: Int32, key: "c0"}, @@ -117,10 +124,12 @@ describe "DB.mapping" do it "should initialize a mapping with nilable types if columns are missing" do expect_mapping("1", MappingWithNilTypes, {c0: 1, c1: nil}) + expect_mapping("1", MappingWithNilUnionTypes, {c0: 1, c1: nil}) end it "should initialize a mapping with nilable types ignoring default value if NULL" do expect_mapping("NULL,a", MappingWithNilTypes, {c0: nil, c1: "a"}) + expect_mapping("NULL,a", MappingWithNilUnionTypes, {c0: nil, c1: "a"}) end it "should initialize a mapping with different keys" do diff --git a/src/db/mapping.cr b/src/db/mapping.cr index f627ec1..d82fb56 100644 --- a/src/db/mapping.cr +++ b/src/db/mapping.cr @@ -66,6 +66,11 @@ module DB {% for key, value in properties %} {% value[:nilable] = true if value[:type].is_a?(Generic) && value[:type].type_vars.map(&.resolve).includes?(Nil) %} + + {% if value[:type].is_a?(Call) && value[:type].name == "|" && + (value[:type].receiver.resolve == Nil || value[:type].args.map(&.resolve).any?(&.==(Nil))) %} + {% value[:nilable] = true %} + {% end %} {% end %} {% for key, value in properties %} @@ -103,7 +108,7 @@ module DB {% if value[:converter] %} {{value[:converter]}}.from_rs(%rs) {% elsif value[:nilable] || value[:default] != nil %} - %rs.read(Union({{value[:type]}} | Nil)) + %rs.read(::Union({{value[:type]}} | Nil)) {% else %} %rs.read({{value[:type]}}) {% end %}