From c0b0e12dce2a753310c9c977d2f9b962d6ef527d Mon Sep 17 00:00:00 2001 From: Jasmijn Wellner Date: Tue, 31 Dec 2024 10:36:41 +0100 Subject: [PATCH] Fix bug #33 by changing the contract "Pray I do not alter it any further." On a serious note, I could not find a good reason to keep the old behaviour. It was niche at best, and class libraries tend to ultimately depend on `setmetatable` anyway, which just returns the original table, which has been mutated. Now the return value of `deserializer` is simply ignored, and it is presumed the original table *is* the instance. --- USAGE.md | 3 +-- bitser.lua | 6 ++---- spec/bitser_spec.lua | 17 ++++++++--------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/USAGE.md b/USAGE.md index 7d6eda1..6a77c2a 100644 --- a/USAGE.md +++ b/USAGE.md @@ -198,8 +198,7 @@ to patch bitser. [See the list of supported class libraries](#supported-class-li If not nil, the argument `classkey` should be a string such that `rawget(obj, classkey) == class` for any `obj` whose type is `class`. This is done so that key is skipped for serialization. -If not nil, the argument `deserializer` should be a function such that `deserializer(obj, class)` returns a valid -instance of `class` with the properties of `obj`. `deserializer` is allowed to mutate `obj`. +If not nil, the argument `deserializer` should be a function such that `deserializer(obj, class)` mutates `obj` in a way that makes it a valid instance of `class`. Returns the registered class as a convenience. diff --git a/bitser.lua b/bitser.lua index a04f3a2..b81fdba 100644 --- a/bitser.lua +++ b/bitser.lua @@ -349,8 +349,7 @@ local function deserialize_value(seen) return value elseif t == 242 then --instance - local instance_idx = reserve_seen(seen) - local instance = {} + local instance = add_to_seen({}, seen) local classname = deserialize_value(seen) local class = class_registry[classname] local classkey = classkey_registry[classname] @@ -367,8 +366,7 @@ local function deserialize_value(seen) if classkey then instance[classkey] = class end - instance = deserializer(instance, class) - seen[instance_idx] = instance + deserializer(instance, class) return instance elseif t == 243 then --reference diff --git a/spec/bitser_spec.lua b/spec/bitser_spec.lua index cc415c4..1c3c3a2 100644 --- a/spec/bitser_spec.lua +++ b/spec/bitser_spec.lua @@ -328,30 +328,29 @@ describe("bitser", function() it("is able to deserialize the same instance twice", function() local class = {} local instance = setmetatable({}, class) - local deserialize = function(_, _) - return instance - end + local deserialize = setmetatable bitser.registerClass("class", class, nil, deserialize) local loaded_instances = serdeser({instance, instance}) - assert.are.equal(instance, loaded_instances[1], loaded_instances[2]) + assert.are.equal(loaded_instances[1], loaded_instances[2]) + assert.are.same(instance, loaded_instances[1]) bitser.unregisterClass("class") end) - it("cannot deserialize an instance nested within itself", function() + it("is able to deserialize an instance nested within itself", function() local class = {} local instance = setmetatable({}, class) - local deserialize = function(_, _) - return instance - end + local deserialize = setmetatable instance.myself = {instance} bitser.registerClass("class", class, nil, deserialize) - assert.has_error(function() serdeser(instance) end, "trying to deserialize a value that has not yet been initialized") + local loaded_instance = serdeser(instance) + assert.are.equal(loaded_instance, loaded_instance.myself[1]) + assert.are.same(instance, loaded_instance) bitser.unregisterClass("class") end)