Skip to content

Commit

Permalink
Clean up old code, add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
penelopeysm committed Sep 27, 2024
1 parent c1613f9 commit 121d1b0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 116 deletions.
145 changes: 31 additions & 114 deletions src/varname.jl
Original file line number Diff line number Diff line change
Expand Up @@ -754,118 +754,6 @@ function vsym(expr::Expr)
end
end

"""
index_to_str(i)
Generates a string representation of the index `i`, or a tuple thereof.
## Examples
```jldoctest
julia> AbstractPPL.index_to_str(2)
"2"
julia> AbstractPPL.index_to_str((1, 2:5))
"(1, 2:5,)"
julia> AbstractPPL.index_to_str(:)
":"
julia> AbstractPPL.index_to_str(AbstractPPL.ConcretizedSlice(Base.Slice(Base.OneTo(10))))
"ConcretizedSlice(Base.OneTo(10))"
```
"""
index_to_str(i::Integer) = string(i)
index_to_str(r::UnitRange) = "$(first(r)):$(last(r))"
index_to_str(::Colon) = ":"
index_to_str(s::ConcretizedSlice{T,R}) where {T,R} = "ConcretizedSlice(" * repr(s.range) * ")"
index_to_str(t::Tuple) = "(" * join(map(index_to_str, t), ", ") * ",)"

"""
optic_to_nt(optic)
Convert an optic to a named tuple representation.
## Examples
```jldoctest; setup=:(using Accessors)
julia> AbstractPPL.optic_to_nt(identity)
(type = "identity",)
julia> AbstractPPL.optic_to_nt(@optic _.a)
(type = "property", field = "a")
julia> AbstractPPL.optic_to_nt(@optic _.a.b)
(type = "composed", outer = (type = "property", field = "b"), inner = (type = "property", field = "a"))
julia> AbstractPPL.optic_to_nt(@optic _[1]) # uses index_to_str()
(type = "index", indices = "(1,)")
```
"""
optic_to_nt(::typeof(identity)) = (type = "identity",)
optic_to_nt(::PropertyLens{sym}) where {sym} = (type = "property", field = String(sym))
optic_to_nt(i::IndexLens) = (type = "index", indices = index_to_str(i.indices))
optic_to_nt(c::ComposedOptic) = (type = "composed", outer = optic_to_nt(c.outer), inner = optic_to_nt(c.inner))


"""
nt_to_optic(nt)
Convert a named tuple representation back to an optic.
"""
function nt_to_optic(nt)
if nt.type == "identity"
return identity
elseif nt.type == "index"
return IndexLens(eval(Meta.parse(nt.indices)))
elseif nt.type == "property"
return PropertyLens{Symbol(nt.field)}()
elseif nt.type == "composed"
return nt_to_optic(nt.outer) nt_to_optic(nt.inner)
end
end

"""
vn_to_string(vn::VarName)
Convert a `VarName` as a string, via an intermediate named tuple. This differs
from `string(vn)` in that concretised slices are faithfully represented (rather
than being pretty-printed as colons).
```jldoctest
julia> vn_to_string(@varname(x))
"(sym = \\"x\\", optic = (type = \\"identity\\",))"
julia> vn_to_string(@varname(x.a))
"(sym = \\"x\\", optic = (type = \\"property\\", field = \\"a\\"))"
julia> y = ones(2); vn_to_string(@varname(y[:]))
"(sym = \\"y\\", optic = (type = \\"index\\", indices = \\"(:,)\\"))"
julia> y = ones(2); vn_to_string(@varname(y[:], true))
"(sym = \\"y\\", optic = (type = \\"index\\", indices = \\"(ConcretizedSlice(Base.OneTo(2)),)\\"))"
```
"""
vn_to_string(vn::VarName) = repr((sym = String(getsym(vn)), optic = optic_to_nt(getoptic(vn))))

"""
vn_from_string(str)
Convert a string representation of a `VarName` back to a `VarName`. The string
should have been generated by `vn_to_string`.
!!! warning
This function should only be used with trusted input, as it uses `eval`
and `Meta.parse` to parse the string.
"""
function vn_from_string(str)
new_fields = eval(Meta.parse(str))
return VarName{Symbol(new_fields.sym)}(nt_to_optic(new_fields.optic))
end

# -----------------------------------------
# Alternate implementation with StructTypes
# -----------------------------------------

index_to_dict(i::Integer) = Dict("type" => "integer", "value" => i)
index_to_dict(v::AbstractVector{Int}) = Dict("type" => "vector", "values" => v)
index_to_dict(r::UnitRange) = Dict("type" => "unitrange", "start" => r.start, "stop" => r.stop)
Expand Down Expand Up @@ -918,6 +806,35 @@ vn_to_dict(vn::VarName) = Dict("sym" => getsym(vn), "optic" => optic_to_dict(get

dict_to_vn(dict::Dict{<:AbstractString, Any}) = VarName{Symbol(dict["sym"])}(dict_to_optic(dict["optic"]))

vn_to_string2(vn::VarName) = JSON.json(vn_to_dict(vn))
"""
vn_to_string(vn::VarName)
Convert a `VarName` as a string, via an intermediate dictionary. This differs
from `string(vn)` in that concretised slices are faithfully represented (rather
than being pretty-printed as colons).
Note that this function only supports a subset of AbstractRange
```jldoctest
julia> vn_to_string(@varname(x))
"{\\"optic\\":{\\"type\\":\\"identity\\"},\\"sym\\":\\"x\\"}"
julia> vn_to_string(@varname(x.a))
"{\\"optic\\":{\\"field\\":\\"a\\",\\"type\\":\\"property\\"},\\"sym\\":\\"x\\"}"
julia> y = ones(2); vn_to_string(@varname(y[:]))
"{\\"optic\\":{\\"indices\\":{\\"values\\":[{\\"type\\":\\"colon\\"}],\\"type\\":\\"tuple\\"},\\"type\\":\\"index\\"},\\"sym\\":\\"y\\"}"
vn_from_string2(str) = dict_to_vn(JSON.parse(str))
julia> y = ones(2); vn_to_string(@varname(y[:], true))
"{\\"optic\\":{\\"indices\\":{\\"values\\":[{\\"oneto\\":2,\\"type\\":\\"concretized_slice\\"}],\\"type\\":\\"tuple\\"},\\"type\\":\\"index\\"},\\"sym\\":\\"y\\"}"
```
"""
vn_to_string(vn::VarName) = JSON.json(vn_to_dict(vn))

"""
vn_from_string(str)
Convert a string representation of a `VarName` back to a `VarName`. The string
should have been generated by `vn_to_string`.
"""
vn_from_string(str) = dict_to_vn(JSON.parse(str))
4 changes: 2 additions & 2 deletions test/varname.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ end
@varname(z[2:5,:], true),
]
for vn in vns
@test vn_from_string2(vn_to_string2(vn)) == vn
@test vn_from_string(vn_to_string(vn)) == vn
end

# For this VarName, the {de,}serialisation works correctly but we must
Expand All @@ -181,7 +181,7 @@ end
# addresses rather than the contents (thus vn_vec == vn_vec2 returns
# false).
vn_vec = @varname(x[[1, 2, 5, 6]])
vn_vec2 = vn_from_string2(vn_to_string2(vn_vec))
vn_vec2 = vn_from_string(vn_to_string(vn_vec))
@test hash(vn_vec) == hash(vn_vec2)
end
end

0 comments on commit 121d1b0

Please sign in to comment.