Mercurial > lbo > hg > juliaplay
changeset 38:bae384998d85
JSON: Improve empty field detector
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sat, 25 Mar 2023 21:19:46 +0100 |
parents | 37a528750178 |
children | 8a21e7a32029 |
files | julia/parallel/ParallelProcessing/src/ParallelProcessing.jl julia/parallel/ParallelProcessing/src/metaparser.jl |
diffstat | 2 files changed, 47 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/julia/parallel/ParallelProcessing/src/ParallelProcessing.jl Fri Mar 24 22:07:52 2023 +0100 +++ b/julia/parallel/ParallelProcessing/src/ParallelProcessing.jl Sat Mar 25 21:19:46 2023 +0100 @@ -1,7 +1,8 @@ module ParallelProcessing -include("json.jl") include("jsonparser.jl") include("metaparser.jl") +include("json.jl") + end # module ParallelProcessing
--- a/julia/parallel/ParallelProcessing/src/metaparser.jl Fri Mar 24 22:07:52 2023 +0100 +++ b/julia/parallel/ParallelProcessing/src/metaparser.jl Sat Mar 25 21:19:46 2023 +0100 @@ -16,11 +16,15 @@ "Field $f in $typedef must be type! (we don't support constructors etc. - struct must be plain)", ) name, typ = f.args - typeof(typ) == Symbol || + + is_type = (typeof(typ) == Symbol || (typeof(typ) == Expr && typ.head == :curly)) + is_type || error("Type of $f should be symbol (simple type) but is $(typeof(typ)): $typ") + typ = eval(typ) isconcretetype(typ) || error("Type of field $name must be concrete, but is not (is $typ)!") + push!(fields_exprs, name => eval(typ)) end @@ -38,22 +42,53 @@ end end +function map_type_to_parse_method(::Type{<:Number})::Symbol + :take_num! +end +function map_type_to_parse_method(::Type{<:AbstractString})::Symbol + :take_str! +end +function map_type_to_parse_method(::Type{Bool})::Symbol + :take_bool! +end +function map_type_to_parse_method(::Type{<:AbstractDict})::Symbol + :take_object! +end +function map_type_to_parse_method(::Type{<:AbstractVector})::Symbol + :take_list! +end +function map_type_to_parse_method(::Type{T})::Symbol where {T} + error("unexpected type") + if isstructtype(T) + :take_struct! + else + error("Unknown type $T for JSON parsing!") + end +end + +function check_variables_filled_expr(varnames::AbstractVector{Symbol})::Vector{Expr} + check_var_cond(sym) = begin + syms = string(sym) + quote + syms = $syms + if isnothing($sym) + error("Field $syms not given in JSON object!") + end + end + end + [check_var_cond(s) for s in varnames] +end + function json_parseable(strct) typs::Vector{Pair{Symbol,Type}} = parse_struct(strct) typ = get_type_of_struct(strct) fieldvars = [:($(name)::Union{$typ,Nothing} = nothing) for (name, typ) in typs] fieldnames = [name for (name, _) in typs] + fields_filled_cond = check_variables_filled_expr(fieldnames) Mod = :ParallelProcessing - method_map = Dict( - Int64 => :take_num!, - Float64 => :take_num!, - String => :take_str!, - Dict => :take_object!, - Bool => :take_bool!, - ) - methods = [(name, method_map[typ]) for (name, typ) in typs] + methods = [(name, map_type_to_parse_method(typ)) for (name, typ) in typs] field_dispatch = [ quote if !matched && key == $(string(name)) @@ -96,9 +131,7 @@ end end - #if $(fields_filled_cond...) - # error("Elements missing from object") - #end + $(fields_filled_cond...) $Mod.expect!(jp, '}') || error("unclosed object")