Skip to content

Commit

Permalink
container: typed UndefProperty
Browse files Browse the repository at this point in the history
attach type to UndefProperty
  • Loading branch information
miRoox committed Nov 6, 2022
1 parent 1bae438 commit 51ee2a3
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 20 deletions.
25 changes: 13 additions & 12 deletions src/container.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@

"""
UndefProperty
UndefProperty{T}
Placeholder for undefined properties in [`Container`](@ref).
"""
struct UndefProperty end
struct UndefProperty{T} end

UndefProperty() = UndefProperty{Any}()

Base.show(io::IO, ::UndefProperty) = print(io, "#undef")

undeftypeof(::UndefProperty{T}) where {T} = T
undeftypeof(obj) = typeof(obj)

"""
Container{T}
Expand All @@ -22,8 +27,8 @@ Create an uninitialized container for `T`.
```jldoctest
julia> Container{Complex{Int64}}()
Container{Complex{Int64}}:
re: #undef
im: #undef
re: Int64 = #undef
im: Int64 = #undef
```
"""
struct Container{T}
Expand All @@ -39,7 +44,7 @@ end

Base.getproperty(obj::Container{T}, name::Symbol) where {T} = get(getfield(obj, 1), name) do
if name in fieldnames(T)
UndefProperty()
UndefProperty{fieldtype(T, name)}()
else
error("type $T has no field $name")
end
Expand Down Expand Up @@ -73,13 +78,9 @@ function Base.show(io::IO, mime::MIME"text/plain", obj::Container)
print(io, " ")
print(io, prop)
print(io, ": ")
if val isa UndefProperty
show(io, val)
else
show(io, typeof(val))
print(io, " = ")
show(io, mime, val)
end
show(io, undeftypeof(val))
print(io, " = ")
show(io, mime, val)
print(io, "\n")
end
end
Expand Down
7 changes: 2 additions & 5 deletions src/macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,6 @@ end
function deducefieldtypes!(fields::Vector{>:FieldInfo})
namedfields = filter(field -> field.name isa Symbol, fields)
for field in fields
if field.type != UndefProperty
continue
end
thistype = NamedTuple{tuple(map(field -> field.name, namedfields)...), Tuple{map(field -> field.type, namedfields)...}}
fieldconstype = deducetype(field.tfunc, thistype)
if fieldconstype !== Union{}
Expand Down Expand Up @@ -232,7 +229,7 @@ function generateserializemethod(constructname::Symbol, structname::Symbol, fiel
push!(sercalls, field.line)
end
if isnothing(field.name)
fielddata = UndefProperty()
fielddata = UndefProperty{field.type}()
else
fielddata = Expr(:(.),
this,
Expand Down Expand Up @@ -370,7 +367,7 @@ function generateestimatesizemethod(constructname::Symbol, structname::Symbol, f
),
escape_excludes(field.cons, [this])
)
# if the construct can't accept UndefProperty() while the code has it,
# if the construct can't accept UndefProperty{T}() while the code has it,
# the size is just UnboundedSize(0) (like any other unknown sized construct)
szcall = Expr(:try,
Expr(:block, szcall),
Expand Down
11 changes: 8 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ end
@test repr(UndefProperty()) == "#undef"
@test_throws ArgumentError Container(1)
@test Container(im).im
@test Container{Complex{Bool}}().im == UndefProperty()
@test Container{Complex{Bool}}().im == UndefProperty{Bool}()
@test_throws ErrorException Container{Complex{Bool}}().i
@test_throws ErrorException Container(im).im = false
@test propertynames(Container(1//2)) == propertynames(1//2)
Expand All @@ -98,8 +98,8 @@ end
"""
@test repr("text/plain", Container{Complex{Int64}}()) == """
Container{Complex{Int64}}:
re: #undef
im: #undef
re: Int64 = #undef
im: Int64 = #undef
"""
end
@testset "primitive io" begin
Expand Down Expand Up @@ -377,6 +377,11 @@ end
@test_throws ValidationError serialize(Const(0x0102), 0x0201)
end
@testset "Overwrite" begin
@testset "deduce type" begin
@test Constructs.deducetype((v) -> Overwrite(UInt8, v), UInt8) <: Construct{UInt8}
@test Constructs.deducetype((v) -> Overwrite(UInt8, v), Function) <: Construct{UInt8}
@test Constructs.deducetype((v) -> Overwrite(UInt8, v), UndefProperty) <: Construct{UInt8}
end
@test_throws ArgumentError Overwrite(UInt8, () -> 0x01)
@test serialize(Overwrite(UInt8, 0x01), 2) == b"\x01"
@test serialize(Overwrite(UInt8, 0x02), UndefProperty()) == b"\x02"
Expand Down

0 comments on commit 51ee2a3

Please sign in to comment.