matio_rs/lib.rs
1/*!
2# Rust bindings and wrappers for [MATIO](https://github.com/tbeu/matio)
3
4This crate provides bindings and wrappers for [MATIO](https://github.com/tbeu/matio):
5MATLAB MAT file I/O C library
6
7## Examples
8
9Saving to a Mat file
10```
11use matio_rs::MatFile;
12# let file = tempfile::NamedTempFile::new().unwrap();
13# let data_path = file.path();
14MatFile::save(data_path)?
15 .var("a", 1i8)?
16 .var("b", 2f32)?
17 .var("c", &vec![3u16; 3])?
18 .var("d", "qwerty")?
19 .var("e", (1.2f64, 3.45f64, 6.789f64))?
20 .var("f", vec!["cogito", "ergo sum"])?;
21# Ok::<(), matio_rs::MatioError>(())
22```
23and then loading the data back into Rust
24```
25# use matio_rs::MatFile;
26# let file = tempfile::NamedTempFile::new().unwrap();
27# let data_path = file.path();
28# MatFile::save(data_path)?
29# .var("a", 1i8)?
30# .var("b", 2f32)?
31# .var("c", &vec![3u16; 3])?
32# .var("d", "qwerty")?
33# .var("e",(1.2f64,3.45f64,6.789f64))?
34# .var("f", vec!["cogito", "ergo sum"])?;
35let mat_file = MatFile::load(data_path)?;
36let a: i8 = mat_file.var("a")?;
37let b: f32 = mat_file.var("b")?;
38let c: Vec<u16> = mat_file.var("c")?;
39let d: String = mat_file.var("d")?;
40let e: Vec<f64> = mat_file.var("e")?;
41let f: Vec<String> = mat_file.var("f")?;
42# Ok::<(), matio_rs::MatioError>(())
43```
44
45Saving data to a Matlab structure
46```
47use matio_rs::{MatFile, Mat, MayBeFrom};
48# let file = tempfile::NamedTempFile::new()?;
49# let data_path = file.path();
50let mat_a = Mat::maybe_from("fa", 123f64)?;
51let b = vec![0i32, 1, 2, 3, 4];
52let mat_v = Mat::maybe_from("fb", &b)?;
53let data = vec![mat_a, mat_v];
54let mat_struct = Mat::maybe_from("s", data)?;
55let mat_file = MatFile::save(data_path)?;
56mat_file.write(mat_struct);
57# Ok::<(), matio_rs::MatioError>(())
58```
59and then loading the structure fields back into Rust variables
60```
61use matio_rs::{MatFile, Mat, MayBeInto};
62# use matio_rs::{MayBeFrom};
63# let file = tempfile::NamedTempFile::new()?;
64# let data_path = file.path();
65# let mat_a = Mat::maybe_from("fa", 123f64)?;
66# let b = vec![0i32, 1, 2, 3, 4];
67# let mat_v = Mat::maybe_from("fb", &b)?;
68# let data = vec![mat_a, mat_v];
69# let mat_struct = Mat::maybe_from("s", data)?;
70# let mat_file = MatFile::save(data_path)?;
71# mat_file.write(mat_struct);
72let mat_file = MatFile::load(&data_path)?;
73let mat: Mat = mat_file.var("s")?;
74let a: f64 = mat
75 .field("fa")?
76 .get(0).unwrap()
77 .maybe_into()?;
78let b: Vec<i32> = mat
79 .field("fb")?
80 .get(0).unwrap()
81 .maybe_into()?;
82# Ok::<(), matio_rs::MatioError>(())
83```
84
85Rust structure with the [MatIO] derive attribute can be dispatched like any other variables:
86```
87use matio_rs::{MatFile, MatIO};
88# use tempfile::NamedTempFile;
89
90#[derive(Debug, Default, MatIO)]
91struct SMat {
92 a: f64,
93 b: Vec<u32>,
94 s: Nested,
95}
96#[derive(Debug, Default, MatIO)]
97struct Nested {
98 a: f64,
99 b: Vec<u32>,
100}
101let n = Nested {
102 a: 1f64,
103 b: vec![2, 3, 4, 5],
104};
105let a = SMat {
106 a: 1f64,
107 b: vec![2, 3, 4, 5],
108 s: n,
109};
110# let file = NamedTempFile::new().unwrap();
111MatFile::save(&file)?.var("a", &a)?;
112let aa: SMat = MatFile::load(file)?.var("a")?;
113# Ok::<(), matio_rs::MatioError>(())
114```
115
116Saving a Rust vector into a 3D Matlab array
117```
118use matio_rs::{MatFile, MatArray};
119# use tempfile::NamedTempFile;
120# let file = NamedTempFile::new().unwrap();
121let data: Vec<_> = (0..24).collect();
122MatFile::save(&file)?
123 .array("array", &data, vec![3, 4, 2])?;
124# Ok::<(), matio_rs::MatioError>(())
125```
126
127[nalgebra](https://docs.rs/nalgebra/latest/nalgebra/) vectors and matrices can be read from and
128 written to Mat files providing the `nalgebra` feature
129```
130use matio_rs::MatFile;
131# use tempfile::NamedTempFile;
132# let file = NamedTempFile::new().unwrap();
133let na_v = nalgebra::DVector::from_iterator(5, 0..5);
134MatFile::save(&file).unwrap().var("na_v", &na_v).unwrap();
135let v: nalgebra::DMatrix<i32> = MatFile::load(file).unwrap().var("na_v").unwrap();
136```
137```
138use matio_rs::MatFile;
139# use tempfile::NamedTempFile;
140# let file = NamedTempFile::new().unwrap();
141let na_m = nalgebra::DMatrix::from_iterator(3, 2, 0..6);
142MatFile::save(&file).unwrap().var("na_m", &na_m).unwrap();
143let m: nalgebra::DMatrix<i32> = MatFile::load(file).unwrap().var("na_m").unwrap();
144```
145*/
146
147use std::{io, string::FromUtf8Error};
148use thiserror::Error;
149
150// mod builder;
151// pub use builder::Builder;
152mod matfile;
153pub use matfile::{MatFile, MatFileRead, MatFileWrite};
154mod datatype;
155pub(crate) use datatype::{DataType, MatType};
156mod mat;
157pub use mat::Mat;
158mod convert;
159pub use convert::{MayBeFrom, MayBeInto};
160pub use derive::MatIO;
161mod mat_array;
162pub use mat_array::MatArray;
163
164#[derive(Error, Debug)]
165pub enum MatioError {
166 #[error("mat file does not exists")]
167 NoFile(#[from] io::Error),
168 #[error("opening mat file {0} failed")]
169 MatOpen(String),
170 #[error("mat file name can't be processed")]
171 MatName(#[from] std::ffi::NulError),
172 #[error("reading mat var {0} failed")]
173 MatVarRead(String),
174 #[error("creating mat var {0} failed")]
175 MatVarCreate(String),
176 #[error("Rust ({0}) and Matlab ({1}) types do not match")]
177 MatType(String, String),
178 #[error("structure fields missing")]
179 NoFields,
180 #[error("structure fields have different sizes {0:?}")]
181 FieldSize(Vec<usize>),
182 #[error("Matlab var. {0}: expected Matlab type {1} found {2}")]
183 TypeMismatch(String, String, String),
184 #[error("Matlab var. {0}: cannot convert a Matlab array of length {0} into a Rust scalar")]
185 Scalar(String, usize),
186 #[error("Field name cannot be converted to &str")]
187 FieldName(#[from] std::str::Utf8Error),
188 #[error("Field {0} not found")]
189 FieldNotFound(String),
190 #[error("expected rank 2, found {0}")]
191 Rank(usize),
192 #[error("failed to convert Matlab char array to String")]
193 CharConversion(#[from] FromUtf8Error),
194}
195pub type Result<T> = std::result::Result<T, MatioError>;