diff --git a/Project.toml b/Project.toml index 85dadac..d4139a1 100644 --- a/Project.toml +++ b/Project.toml @@ -1,17 +1,18 @@ name = "StructHelpers" uuid = "4093c41a-2008-41fd-82b8-e3f9d02b504f" authors = ["Jan Weidner and contributors"] -version = "1.1" +version = "1.1.0" [deps] ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" [compat] -julia = "1.6" ConstructionBase = "1.3" +julia = "1.6" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" [targets] -test = ["Test"] +test = ["Test", "StructTypes"] diff --git a/src/StructHelpers.jl b/src/StructHelpers.jl index dbc5505..5e26b2a 100644 --- a/src/StructHelpers.jl +++ b/src/StructHelpers.jl @@ -82,6 +82,7 @@ const BATTERIES_DEFAULTS = ( getproperties = true , constructorof = true , typesalt = nothing, + StructTypes = false, ) const BATTERIES_DOCSTRINGS = ( @@ -94,6 +95,7 @@ const BATTERIES_DOCSTRINGS = ( getproperties = "Overload `ConstructionBase.getproperties`.", constructorof = "Overload `ConstructionBase.constructorof`.", typesalt = "Only used if `hash=true`. In this case the `hash` will be purely computed from `typesalt` and `hash_eq_as(obj)`. The type `T` will not be used otherwise. This makes the hash more likely to stay constant, when executing on a different machine or julia version", + StructTypes = "Overload `StructTypes.StructType` to be `Struct()`. Needs the `StructTypes.jl` package to be installed.", ) if (keys(BATTERIES_DEFAULTS) != keys(BATTERIES_DOCSTRINGS)) @@ -179,6 +181,11 @@ macro batteries(T, kw...) if need_fieldnames fieldnames = Base.fieldnames(Base.eval(__module__, T)) end + need_StructTypes = nt.StructTypes + ST = gensym("ST") + if need_StructTypes + push!(ret.args, :(import StructTypes as $ST)) + end if nt.hash def = :(function Base.hash(o::$T, h::UInt) h = ($start_hash)(o, h, $(nt.typesalt)) @@ -222,6 +229,10 @@ macro batteries(T, kw...) def = def_selfconstructor(T) push!(ret.args, def) end + if nt.StructTypes + def = :($ST.StructType(::Type{<:$T}) = $ST.Struct()) + push!(ret.args, def) + end return esc(ret) end diff --git a/test/runtests.jl b/test/runtests.jl index b361c52..db51062 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -166,6 +166,7 @@ struct Bad end @test_throws "`typesalt` must be literally `nothing` or an unsigned integer." @macroexpand @batteries Bad typesalt = "ouch" @test_throws "Unsupported keyword." @macroexpand @batteries Bad does_not_exist = true @test_throws "Bad keyword argument value" @macroexpand @batteries Bad hash=:nonsense + @test_throws "Bad keyword argument value" @macroexpand @batteries Bad StructTypes=:nonsense end end @@ -235,3 +236,15 @@ Base.:(==)(::HashEqErr, ::HashEqErr) = error() @test SH.structural_hash(S(2,NaN), UInt(0)) == SH.structural_hash(S(2,NaN), UInt(0)) @test SH.structural_hash(S(2,NaN), UInt(0)) != SH.structural_hash(S(2,NaN), UInt(1)) end + +struct WithStructTypes + x + y +end +SH.@batteries WithStructTypes StructTypes=true + +import StructTypes as ST +@testset "StructTypes" begin + with = WithStructTypes(1,2) + @test ST.StructType(typeof(with)) == ST.Struct() +end