Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/chunkkeyencoding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,73 @@ function lower_chunk_key_encoding(e::SuffixChunkKeyEncoding)
)
end

"""Stores a registered chunk key encoding parser together with its expected return type."""
struct ChunkKeyEncodingEntry
return_type::Type{<:AbstractChunkKeyEncoding}
parser::Function
end

"""
Registry mapping chunk key encoding names to `ChunkKeyEncodingEntry` values
(return type + parser function). Use `register_chunk_key_encoding` to add new entries.
"""
const chunk_key_encoding_parsers = Dict{String, ChunkKeyEncodingEntry}()

"""
register_chunk_key_encoding(parser::Function, name::String[, ::Type{T}])

Register a chunk key encoding parser under `name`. The parser must accept a
`Dict{String,Any}` configuration and return an `AbstractChunkKeyEncoding`.

The optional trailing `Type{T}` argument narrows the declared return type stored
in the registry (defaults to `AbstractChunkKeyEncoding`). Specifying it enables
a runtime assertion in `parse_chunk_key_encoding` and makes the registry
self-documenting.

Supports do-block syntax:

register_chunk_key_encoding("myenc") do config
MyEncoding(config["param"])
end

register_chunk_key_encoding("myenc", MyEncoding) do config
MyEncoding(config["param"])
end
"""
function register_chunk_key_encoding(parser::Function, name::String, ::Type{T}) where {T<:AbstractChunkKeyEncoding}
chunk_key_encoding_parsers[name] = ChunkKeyEncodingEntry(T, parser)
end
register_chunk_key_encoding(parser::Function, name::String) =
register_chunk_key_encoding(parser, name, AbstractChunkKeyEncoding)

"""
parse_chunk_key_encoding(d::AbstractDict) -> AbstractChunkKeyEncoding

Parse a chunk key encoding dict (as found in `zarr.json`) into an
`AbstractChunkKeyEncoding` by looking up the registered parser for the encoding name.
"""
function parse_chunk_key_encoding(d::AbstractDict)::AbstractChunkKeyEncoding
name = d["name"]
config = get(d, "configuration", Dict{String,Any}())::Dict{String,Any}
haskey(chunk_key_encoding_parsers, name) ||
throw(ArgumentError("Unknown chunk_key_encoding of name, $name"))
entry = chunk_key_encoding_parsers[name]
return entry.parser(config)::entry.return_type
end

# Register built-in encodings
register_chunk_key_encoding("default", ChunkKeyEncoding) do config
ChunkKeyEncoding(only(get(config, "separator", '/')), true)
end

register_chunk_key_encoding("v2", ChunkKeyEncoding) do config
ChunkKeyEncoding(only(get(config, "separator", '.')), false)
end

register_chunk_key_encoding("suffix", SuffixChunkKeyEncoding) do config
suffix_str = config["suffix"]
base = parse_chunk_key_encoding(config["base_encoding"])
SuffixChunkKeyEncoding(suffix_str, base)
end

_concatpath(p,s) = isempty(p) ? s : rstrip(p,'/') * '/' * s
2 changes: 1 addition & 1 deletion src/metadata.jl
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ function Metadata(A::AbstractArray{T,N}, chunks::NTuple{N,Int}, ::ZarrFormat{2};
)
end

Metadata(s::Union{AbstractString, IO}, fill_as_missing) = Metadata(JSON.parse(s; dicttype=Dict), fill_as_missing)
Metadata(s::Union{AbstractString, IO}, fill_as_missing) = Metadata(JSON.parse(s; dicttype=Dict{String,Any}), fill_as_missing)

"Construct Metadata from Dict"
function Metadata(d::AbstractDict, fill_as_missing)
Expand Down
19 changes: 0 additions & 19 deletions src/metadata3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -151,22 +151,6 @@ function get_order(md::MetadataV3)
end
get_order(md::MetadataV2) = md.order

"""Parse a chunk_key_encoding dict into an `AbstractChunkKeyEncoding` value."""
function parse_chunk_key_encoding(d::AbstractDict)
name = d["name"]
config = get(d, "configuration", Dict{String,Any}())
if name == "default"
return ChunkKeyEncoding(only(get(config, "separator", '/')), true)
elseif name == "v2"
return ChunkKeyEncoding(only(get(config, "separator", '.')), false)
elseif name == "suffix"
suffix_str = config["suffix"]
base = parse_chunk_key_encoding(config["base_encoding"])
return SuffixChunkKeyEncoding(suffix_str, base)
else
throw(ArgumentError("Unknown chunk_key_encoding of name, $name"))
end
end


function Metadata3(d::AbstractDict, fill_as_missing)
Expand Down Expand Up @@ -238,9 +222,6 @@ function Metadata3(d::AbstractDict, fill_as_missing)

# Chunk Key Encoding
chunk_key_encoding = d["chunk_key_encoding"]
if chunk_key_encoding["name"] ∉ ("default", "v2", "suffix")
throw(ArgumentError("Unknown chunk_key_encoding of name, $(chunk_key_encoding["name"])"))
end

# Build V3Pipeline from codec chain
array_array_codecs = []
Expand Down
Loading