-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathPackedSerialization.jl
More file actions
86 lines (72 loc) · 2.45 KB
/
PackedSerialization.jl
File metadata and controls
86 lines (72 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
function pack end
function unpack end
version(::Type{T}) where {T} = pkgversion(parentmodule(T))
# version(node) = node.version
# Type for storing packed type information
struct TypeMetadata
pkg::Symbol #TODO use PkgId, maybe best to use flat structure with optional uuid, something like pkg[_name], pkg_uuid::Union{Nothing, UUID}
name::Symbol
version::Union{Nothing, VersionNumber}
end
function TypeMetadata(::Type{T}) where {T}
return TypeMetadata(fullname(parentmodule(T))[1], nameof(T), version(T))
end
StructUtils.@nonstruct struct Packed{T}
type::TypeMetadata
packed::T
end
function Packed(x)
packedx = pack(x)
return Packed(TypeMetadata(typeof(packedx)), packedx)
end
function StructUtils.lower(x::Packed)
d = StructUtils.make(OrderedDict{Symbol, Any}, x.packed)
push!(d, :type => x.type)
return d
end
function StructUtils.lift(::Type{<:Packed{T}}, x) where {T}
r = unpack(StructUtils.make(T, x))
return r
end
function pack_lower(x)
px = Packed(x)
d = StructUtils.make(OrderedDict{Symbol, Any}, px.packed)
push!(d, :type => px.type)
return d
end
unpack(x) = x
unpack(p::Packed) = unpack(p.packed)
pack(x) = x
#TODO add overwriteable layer
function resolvePackedType(lazyobj::JSON.LazyValue)
type = JSON.parse(lazyobj.type)
# TODO we can use Base.PkgId to not require modules to be available in Main
pkg = Base.require(Main, Symbol(type.pkg))
if !isdefined(Main, Symbol(type.pkg))
throw(SerializationError("Module $(pkg) is available, but not loaded in `Main`."))
end
return Packed{getfield(pkg, Symbol(type.name))}
end
function resolvePackedType(obj::JSON.Object)
type = obj.type
pkg = Base.require(Main, Symbol(type.pkg))
if !isdefined(Main, Symbol(type.pkg))
throw(SerializationError("Module $(pkg) is available, but not loaded in `Main`."))
end
return Packed{getfield(pkg, Symbol(type.name))}
end
function resolveType(obj::DFG.JSON.Object)
type = obj.type
pkg = Base.require(Main, Symbol(type.pkg))
if !isdefined(Main, Symbol(type.pkg))
throw(SerializationError("Module $(pkg) is available, but not loaded in `Main`."))
end
return getfield(pkg, Symbol(type.name))
end
@choosetype Packed resolvePackedType
# Stash optional TypeMetadata expansion function.
# function expandTypeMetadata(;kwargs...)
# md = StructUtils.make(OrderedDict{Symbol, Any}, TypeMetadata(FactorDFG))
# push!(md, kwargs...)
# return md
# end