matrw

Crates.iomatrw
lib.rsmatrw
version0.1.3
created_at2025-10-27 01:20:42.239339+00
updated_at2026-01-11 00:36:50.255089+00
descriptionMAT-file serializing and deserializing
homepage
repositoryhttps://github.com/cpfist/matrw
max_upload_size
id1902099
size453,077
Christian Pfister (cpfist)

documentation

README

matrw   Tests Crates.io Docs.rs License

matrw is a pure Rust library for serializing and deserializing MATLAB MAT-files.

Highlights

  • Read and write of basic MATLAB array types (numeric, structure, cell, sparse).
  • Support of MAT-file compression.
  • Convence methods and macros for access and creation of data (see Untyped interface).
  • Serde interface (see Typed interface).

Introduction

MAT-files store structured numerical data in a binary format. This library offers a serde_json-like interface for ergonomically reading and writing MAT-file data.

Currently, matrw supports serialization and deserialization of version 7 MAT-files. The parser currently handles the following data types:

  • numeric arrays
  • structure arrays
  • cell arrays
  • sparse arrays
  • MCOS/Handle/Java objects (not yet supported)

[!WARNING] The public API isn’t fully stable yet — breaking changes may occur in future versions.

Quickstart

Two interfaces are available:

  • Untyped — if data layout is unknown at compile time.
  • Typed — if data layout is known at compile time.

Untyped interface

The untyped interface represents all possible MAT-file data types using the MatVariable enum. The matfile and matvar macros provide convenient ways to construct MAT-file data from native Rust types.

use matrw::{matfile, matvar, save_matfile_v7, load_matfile};

// Create a MAT-file with variables "a", "b", "c", ...
let mat = matfile!(
    // scalar number
    a: matvar!(1),
    // scalar character
    b: matvar!('c'),
    // empty value
    c: matvar!([]),
    // vector
    d: matvar!([1, 2, 3]),
    // character array
    e: matvar!("asd"),
    // 2x2 matrix
    f: matvar!([
            [1, 2],
            [3, 4],
        ]),
    // 2x2x2 array
    g: matvar!([
            [
                [1, 2],
                [3, 4],
            ],
            [
                [5, 6],
                [7, 8],
            ],
        ]),
    // scalar struct
    h: matvar!({
            f1: 42.,
            f2: "abc",
        }),
    // struct array
    i: matvar!([
            {
                f1: 42.,
                f2: "test",
                f3: 1.,
            },
            {
                f1: 43.,
                f2: "test1",
                f3: 2.,
            },
        ]),
    // empty struct
    j: matvar!({}),
    // cell array
    k: matvar!([
            "abc",
            42.,
            1,
        ])
);

// Write MAT-file without using compression
let _ = save_matfile_v7("test.mat", mat, false);

// ============================================================================

// Load MAT-file
let mat = load_matfile("test.mat").expect("Could not read file.");

// Inspect data
// Access variable "a" and convert it to i32
assert_eq!(mat["a"].to_i32(), Some(1));
// Access variable "b" and convert element "2" to i32
assert_eq!(mat["d"].elem(2).to_i32(), Some(3));
// Access variable "f" and convert element "(1,1)" to i32
assert_eq!(mat["f"].elem([1,1]).to_i32(), Some(4));
// Access variable "g" and convert element "[1,0,1]" to i32
assert_eq!(mat["g"].elem([1,0,1]).to_i32(), Some(7));
// Access variable "h", then field "f1" and convert to f64
assert_eq!(mat["h"]["f1"].to_f64(), Some(42.));
// Access variable "i", then struct index "1" and convert to f64
assert_eq!(mat["i"][1]["f3"].to_f64(), Some(2.));
// Access variable "k", then cell index "1" and convert to f64
assert_eq!(mat["k"][1].to_f64(), Some(42.));

Typed interface

If the data structure is known at compile time, serialization and deserialization can also be done using the serde interface.

use matrw::{save_matfile_v7, to_matfile, load_matfile, from_matfile};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct MyMat {
    a: i32,
    b: char,
    d: Vec<i32>,
    e: String,
    h: S,
}

#[derive(Serialize, Deserialize)]
struct S {
    f1: f64,
    f2: String,
}

let data = MyMat { 
    a: 1, 
    b: 'c', 
    d: vec![1, 2, 3], 
    e: "asd".to_string(), 
    h: S { 
        f1: 42., 
        f2: "abc".to_string() 
    } 
};

let mat = to_matfile(data).expect("Cannot serialize data");
let _ = save_matfile_v7("test.mat", mat, false);

// ============================================================================

// Load MAT-file
let matfile = load_matfile("test.mat").expect("Cannot not read file.");
let mat: MyMat = from_matfile(&matfile).expect("Cannot deserialize data");

// Inspect data
assert_eq!(mat.a, 1);
assert_eq!(mat.d[2], 3);
assert_eq!(mat.e, "asd".to_string());
assert_eq!(mat.h.f1, 42.);
Commit count: 10

cargo fmt