From dda8446d3cc5b704ce73ae9e98b5c4b5a33af06f Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Thu, 10 Oct 2019 06:51:04 +0200 Subject: [PATCH] add setpropertiesgit status demo --- src/ConstructionBase.jl | 24 +++++++++++++++++++++++- test/runtests.jl | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/ConstructionBase.jl b/src/ConstructionBase.jl index 3f4a788..9430c41 100644 --- a/src/ConstructionBase.jl +++ b/src/ConstructionBase.jl @@ -1,8 +1,9 @@ module ConstructionBase -export setproperties +export setproperties, setproperties!, setproperties!! export constructorof + # Use markdown files as docstring: for (name, path) in [ :ConstructionBase => joinpath(dirname(@__DIR__), "README.md"), @@ -72,5 +73,26 @@ function setproperties_unknown_field_error(obj, patch) throw(ArgumentError(msg)) end +function setproperties!(obj, patch::NamedTuple) + _setproperties!(obj, pairs(patch)...) +end + +_setproperties!(obj) = obj + +function _setproperties!(obj, (key, val), tail...) + Base.setproperty!(obj, key, val) + _setproperties!(obj, tail...) +end + +ismutablestruct(x) = ismutablestruct(typeof(x)) +Base.@pure ismutablestruct(T::DataType) = T.mutable + +function setproperties!!(obj, patch::NamedTuple) + if ismutablestruct(obj) + setproperties!(obj, patch) + else + setproperties(obj, patch) + end +end end # module diff --git a/test/runtests.jl b/test/runtests.jl index 24bc7bb..5019b95 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -47,3 +47,36 @@ end @inferred setproperties((a=1, b=2), a=1.0) @inferred setproperties((a=1, b=2), (a=1.0,)) end + +mutable struct TwoMutableInts + a::Int + b::Int +end + +struct TwoImmutableInts + a::Int + b::Int +end + +@testset "setproperties!" begin + o = TwoMutableInts(1,2) + o2 = @inferred setproperties!(o, (a=10, b=20)) + @test o2 isa TwoMutableInts + @test o2.a === 10 + @test o2.b === 20 + + @test o.a === 10 + @test o.b === 20 +end + +@testset "setproperties!!" begin + o = TwoImmutableInts(1,2) + o2 = @inferred setproperties!!(o, (a=10, b=20)) + @test o2 === TwoImmutableInts(10, 20) + + o = TwoMutableInts(1,2) + o2 = @inferred setproperties!!(o, (a=10, b=20)) + @test o2 isa TwoMutableInts + @test o2.a === 10 + @test o2.b === 20 +end