From dfd2c212e2db6434066767a275c9d12ecd794782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Mon, 28 Dec 2020 21:21:32 +0100 Subject: [PATCH] Support more literal types in use_yaml_discriminator --- spec/std/yaml/serializable_spec.cr | 41 ++++++++++++++++++++++++++++++ src/yaml/serialization.cr | 3 +++ 2 files changed, 44 insertions(+) diff --git a/spec/std/yaml/serializable_spec.cr b/spec/std/yaml/serializable_spec.cr index 6009d00b0880..17d48ca25d33 100644 --- a/spec/std/yaml/serializable_spec.cr +++ b/spec/std/yaml/serializable_spec.cr @@ -347,6 +347,33 @@ class YAMLWithShape property shape : YAMLShape end +enum YAMLVariableDiscriminatorEnumFoo + Foo = 4 +end + +class YAMLVariableDiscriminatorValueType + include YAML::Serializable + + use_yaml_discriminator "type", { + 0 => YAMLVariableDiscriminatorNumber, + "1" => YAMLVariableDiscriminatorString, + true => YAMLVariableDiscriminatorBool, + YAMLVariableDiscriminatorEnumFoo::Foo => YAMLVariableDiscriminatorEnum, + } +end + +class YAMLVariableDiscriminatorNumber < YAMLVariableDiscriminatorValueType +end + +class YAMLVariableDiscriminatorString < YAMLVariableDiscriminatorValueType +end + +class YAMLVariableDiscriminatorBool < YAMLVariableDiscriminatorValueType +end + +class YAMLVariableDiscriminatorEnum < YAMLVariableDiscriminatorValueType +end + describe "YAML::Serializable" do it "works with record" do YAMLAttrPoint.new(1, 2).to_yaml.should eq "---\nx: 1\ny: 2\n" @@ -891,6 +918,20 @@ describe "YAML::Serializable" do point.x.should eq(1) point.y.should eq(2) end + + it "deserializes with variable discriminator value type" do + object_number = YAMLVariableDiscriminatorValueType.from_yaml(%({"type": 0})) + object_number.should be_a(YAMLVariableDiscriminatorNumber) + + object_string = YAMLVariableDiscriminatorValueType.from_yaml(%({"type": "1"})) + object_string.should be_a(YAMLVariableDiscriminatorString) + + object_bool = YAMLVariableDiscriminatorValueType.from_yaml(%({"type": true})) + object_bool.should be_a(YAMLVariableDiscriminatorBool) + + object_enum = YAMLVariableDiscriminatorValueType.from_yaml(%({"type": 4})) + object_enum.should be_a(YAMLVariableDiscriminatorEnum) + end end describe "namespaced classes" do diff --git a/src/yaml/serialization.cr b/src/yaml/serialization.cr index 0a3f2040292f..dfd6ee1b08b0 100644 --- a/src/yaml/serialization.cr +++ b/src/yaml/serialization.cr @@ -401,6 +401,9 @@ module YAML discriminator_value = value.value case discriminator_value {% for key, value in mapping %} + {% if key.is_a?(Path) %} + {% key = key.resolve %} + {% end %} when {{key.id.stringify}} return {{value.id}}.new(ctx, node) {% end %}