@@ -34,6 +34,7 @@ import Dates
3434import Dates: DateTime, Second, Millisecond
3535import PooledArrays: PooledArray, RefArray
3636using Tables: Tables
37+ import OrderedCollections: OrderedDict
3738
3839export MatlabStructArray, StructArrayField, convert_struct_array
3940export MatlabClassObject
@@ -68,7 +69,7 @@ using MAT
6869s_arr = MatlabStructArray(["a", "b"], [[1, 2],["foo", 5]])
6970
7071# write-read
71- matwrite("matfile.mat", Dict("struct_array" => s_arr))
72+ matwrite("matfile.mat", Dict{String,Any} ("struct_array" => s_arr))
7273read_s_arr = matread("matfile.mat")["struct_array"]
7374
7475# convert to Dict Array
@@ -144,6 +145,8 @@ Base.haskey(arr::MatlabStructArray, k::AbstractString) = k in keys(arr)
144145function Base. copy (arr:: MatlabStructArray{N} ) where {N}
145146 return MatlabStructArray {N} (copy (arr. names), copy (arr. values))
146147end
148+ class (arr:: MatlabStructArray ) = arr. class
149+ class (d:: AbstractDict ) = " "
147150
148151function Base. iterate (arr:: T , i= next_state (arr)) where {T<: MatlabStructArray }
149152 if i == 0
@@ -284,7 +287,7 @@ Internal Marker for Empty Structs with dimensions like 1x0 or 0x0
284287struct EmptyStruct
285288 dims:: Vector{UInt64}
286289end
287-
290+ class (m :: EmptyStruct ) = " "
288291
289292"""
290293 MatlabClassObject(
@@ -296,11 +299,13 @@ Type to store old class objects. Inside MATLAB a class named \"TestClassOld\" wo
296299
297300If you want to write these objects you have to make sure the keys in the Dict match the class defined properties/fields.
298301"""
299- struct MatlabClassObject <: AbstractDict{String,Any}
300- d:: Dict{String,Any}
302+ struct MatlabClassObject{D <: AbstractDict{String,Any} } <: AbstractDict{String,Any}
303+ d:: D
301304 class:: String
302305end
303306
307+ class (m:: MatlabClassObject ) = m. class
308+
304309Base. eltype (:: Type{MatlabClassObject} ) = Pair{String,Any}
305310Base. length (m:: MatlabClassObject ) = length (m. d)
306311Base. keys (m:: MatlabClassObject ) = keys (m. d)
@@ -320,7 +325,7 @@ function Base.isapprox(m1::MatlabClassObject, m2::MatlabClassObject; kwargs...)
320325 return m1. class == m2. class && dict_isapprox (m1. d, m2. d; kwargs... )
321326end
322327
323- function MatlabStructArray (arr:: AbstractArray{MatlabClassObject} )
328+ function MatlabStructArray (arr:: AbstractArray{<: MatlabClassObject} )
324329 first_obj, remaining_obj = Iterators. peel (arr)
325330 class = first_obj. class
326331 if ! all (x -> isequal (class, x. class), remaining_obj)
@@ -331,7 +336,7 @@ function MatlabStructArray(arr::AbstractArray{MatlabClassObject})
331336 return MatlabStructArray (arr, class)
332337end
333338
334- function convert_struct_array (d:: Dict {String,Any} , class:: String = " " )
339+ function convert_struct_array (d:: AbstractDict {String,Any} , class:: String = " " )
335340 # there is no possibility of having cell arrays mixed with struct arrays (afaik)
336341 field_values = first (values (d))
337342 if field_values isa StructArrayField
@@ -351,13 +356,15 @@ function Base.Array(arr::MatlabStructArray{N}) where {N}
351356 if isempty (arr. class)
352357 return Array {Dict{String,Any},N} (arr)
353358 else
354- return Array {MatlabClassObject,N} (arr)
359+ # ordered dict by default, to preserve field order
360+ D = OrderedDict{String,Any}
361+ return Array {MatlabClassObject{D},N} (arr)
355362 end
356363end
357364
358- function create_struct (:: Type{D} , keys, values, class:: String ) where {D<: MatlabClassObject }
359- d = Dict {String,Any} (string .(keys) .=> values)
360- return MatlabClassObject (d, class)
365+ function create_struct (:: Type{MatlabClassObject{D}} , keys, values, class:: String ) where {D<: AbstractDict }
366+ d = D (string .(keys) .=> values)
367+ return MatlabClassObject {D} (d, class)
361368end
362369
363370"""
@@ -370,10 +377,11 @@ Type to store opaque class objects.
370377These are the 'modern' Matlab classes, different from the old `MatlabClassObject` types.
371378
372379"""
373- struct MatlabOpaque <: AbstractDict{String,Any}
374- d:: Dict{String,Any}
380+ struct MatlabOpaque{D <: AbstractDict{String,Any} } <: AbstractDict{String,Any}
381+ d:: D
375382 class:: String
376383end
384+ class (m:: MatlabOpaque ) = m. class
377385
378386Base. eltype (:: Type{MatlabOpaque} ) = Pair{String,Any}
379387Base. length (m:: MatlabOpaque ) = length (m. d)
492500
493501function MatlabOpaque (d:: ScalarOrArray{DateTime} )
494502 return MatlabOpaque (
495- Dict (
503+ Dict {String,Any} (
496504 " tz" => " " ,
497505 " data" => map_or_not (to_matlab_data, d),
498506 " fmt" => " " ,
@@ -514,7 +522,7 @@ to_matlab_millis(d::Millisecond) = Float64(Dates.value(d))
514522
515523function MatlabOpaque (d:: ScalarOrArray{Millisecond} )
516524 return MatlabOpaque (
517- Dict (
525+ Dict {String,Any} (
518526 " millis" => map_or_not (to_matlab_millis, d),
519527 ),
520528 " duration"
0 commit comments