Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tokazama/metadata.jl
Generic interface for attaching metadata to stuff.
https://github.com/tokazama/metadata.jl
Last synced: about 1 month ago
JSON representation
Generic interface for attaching metadata to stuff.
- Host: GitHub
- URL: https://github.com/tokazama/metadata.jl
- Owner: Tokazama
- License: mit
- Created: 2020-08-20T14:19:26.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2022-04-11T12:29:49.000Z (over 2 years ago)
- Last Synced: 2024-10-10T09:38:40.395Z (about 1 month ago)
- Language: Julia
- Size: 517 KB
- Stars: 13
- Watchers: 2
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Metadata.jl
![CI](https://github.com/Tokazama/Metadata.jl/workflows/CI/badge.svg)
[![stable-docs](https://img.shields.io/badge/docs-stable-blue.svg)](https://Tokazama.github.io/Metadata.jl/stable)
[![dev-docs](https://img.shields.io/badge/docs-dev-blue.svg)](https://Tokazama.github.io/Metadata.jl/dev)
[![codecov](https://codecov.io/gh/Tokazama/Metadata.jl/branch/master/graph/badge.svg?token=hx7hbIIoxE)](https://codecov.io/gh/Tokazama/Metadata.jl)# Introduction
The term "metadata" is widely used across very different applications.
Therefore, "metadata" may translate to very different structures and implementations in code.
The `Metadata` package attempts to provide a generic interface for interacting with metadata in Julia that is agnostic to the exact type of metadata present.
This package typically assumes metadata to be a collection of values paired to `Symbol` keys (e.g., `AbstractDict{Symbol,Any}`, `NamedTuple`), but metadata that doesn't perfectly fit this criteria should still work with most methods if adhering to the basic interface.# Attaching Metadata
The most important method to know is `attach_metadata`.
It's intended to give users a generic way of attaching metadata to any given type without worrying about the particulars what type is appropriate for binding metadata to a particular.
For example, attaching metadata to an array should produce something that can act like an array still.
Instead of requiring users to know what type is used internally (`Metadata.MetaArray`), an appropriate type is chosen by default and the method of accessing metadata is the same.
```julia
julia> using Metadatajulia> x = ones(2, 2);
julia> meta = (x = 1, y = 2);
julia> mx = attach_metadata(x, meta)
2×2 attach_metadata(::Matrix{Float64}, ::NamedTuple{(:x, :y), Tuple{Int64, Int64}}
• metadata:
x = 1
y = 2
)
1.0 1.0
1.0 1.0julia> mx.x
1julia> mx.y
2julia> attach_metadata(x, (x = 1, y = 2, suppress= [:x]))
2×2 attach_metadata(::Matrix{Float64}, ::NamedTuple{(:x, :y, :suppress), Tuple{Int64, Int64, Vector{Symbol}}}
• metadata:
x =
y = 2
)
1.0 1.0
1.0 1.0```
There are three things you should notice from the previous example:
1. The display is nearly identical to how the parent `x` would be printed. The only addition is a list of the metadata and the argument used to bind the `x` and `meta`.
2. We can access the metadata as if they were properties.
3. We can suppress the printing of any value if `metadata(x, :suppress)` returns a collection of symbols containing that value.There are a limited number of interfaces that require special types for binding metadata.
The rest are bound to `Metadata.MetaStruct`.
```julia
julia> mr = attach_metadata(3//5, meta)
attach_metadata(3//5, ::NamedTuple{(:x, :y), Tuple{Int64, Int64}})
• metadata:
x = 1
y = 2julia> propertynames(mr)
(:x, :y)julia> mr.num
3julia> mr.den
5
```
Here we attached the same metadata to a rational number.
Again, our metadata is now considered the properties of `mr`, but we can still access the parent's properties.# Creating New Metadata Types
This package creates a very minimal number of dedicated structures and creating new dedicated structures that use this interface is encouraged.
```
abstract type AbstractNoop endstruct Noop <: AbstractNoop end
struct MetaNoop{P<:AbstractNoop,M} <: AbstractNoop
parent::P
metadata::M
endMetadata.metadata(x::MetaNoop) = getfield(x, :metadata)
Metadata.unsafe_attach_metadata(x::AbstractNoop, m) = MetaNoop(x, m)
Metadata.metadata_type(::Type{MetaNoop{P,M}}) where {P,M} = MArrayInterface.parent_type(::Type{MetaNoop{P,M}}) where {P,M} = P
Base.parent(x::MetaNoop) = getfield(x, :parent)
```It's advised that `Metadata.test_wrapper(MetaNoop, Noop())` is run to ensure it works.
Note that using the dot operator (`.`) that aliases `getproperty` and `setproperty!` is not necessary.