diff --git a/src/StructArrays.jl b/src/StructArrays.jl index 7c1b1dd0..e247e3c6 100644 --- a/src/StructArrays.jl +++ b/src/StructArrays.jl @@ -25,6 +25,19 @@ function refvalue(s::StructArray{T}, v::Tup) where {T} createinstance(T, map(refvalue, components(s), v)...) end +# implement colmetadata for StructArray based on metadata of individual columns +import DataAPI: metadata, metadatasupport, colmetadata, colmetadatasupport + +colmetadatasupport(::Type{T}) where {T<:StructArray} = ( + read=any(col -> metadatasupport(col).read, array_types(T).parameters), + write=false, # not implemented +) +colmetadata(sa::StructArray, col::Symbol) = metadata(getproperty(sa, col)) +colmetadata(sa::StructArray) = + map(Tables.columns(sa)) do col + metadatasupport(typeof(col)).read ? metadata(col) : nothing + end + @static if !isdefined(Base, :get_extension) include("../ext/StructArraysAdaptExt.jl") include("../ext/StructArraysGPUArraysCoreExt.jl") diff --git a/test/runtests.jl b/test/runtests.jl index 47c15645..0a511488 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1189,6 +1189,24 @@ end end end +@testset "metadata" begin + using DataAPI: colmetadatasupport, colmetadata, metadata, DataAPI + + struct MyArray <: AbstractVector{Int} end + Base.size(::MyArray) = (2,) + DataAPI.metadatasupport(::Type{<:MyArray}) = (read=true, write=false) + DataAPI.metadata(::MyArray) = (x=1, y="2") + + sa = StructArray(a=[1,2], b=[1,2]) + @test colmetadatasupport(typeof(sa)) == (read=false, write=false) + + sa = StructArray(a=MyArray(), b=[1,2]) + @test metadata(sa.a) == (x=1, y="2") + @test colmetadatasupport(typeof(sa)) == (read=true, write=false) + @test colmetadata(sa, :a) == (x=1, y="2") + @test colmetadata(sa) == (a=(x=1, y="2"), b=nothing) +end + struct ArrayConverter end Adapt.adapt_storage(::ArrayConverter, xs::AbstractArray) = convert(Array, xs)