Skip to main content

matten/
lib.rs

1//! `matten` — a developer-experience-first multidimensional array (tensor)
2//! library for Rust.
3//!
4//! `matten` is a *family car* of Rust tensor library: easy to start,
5//! predictable, and friendly for non-expert Rust developers doing small
6//! numerical, data-exploration, or business proof-of-concept work. It
7//! deliberately prioritizes **developer experience over peak performance**, and
8//! is not a replacement for `ndarray`, `nalgebra`, or `candle` on hot paths.
9//!
10//! # Scope
11//!
12//! Phase 1 (numeric `f64` core): construction, shape operations, arithmetic,
13//! broadcasting, slicing, reductions, matrix multiplication, JSON/CSV boundary
14//! APIs, and serde integration — all complete.
15//!
16//! The `dynamic` feature (`features = ["dynamic"]`) supports heterogeneous
17//! ingestion and missing-value cleanup before conversion to numeric tensors via
18//! [`Tensor::try_numeric`]. Dynamic reshape/slicing/arithmetic are intentionally
19//! guarded until a future CoW-view milestone.
20//!
21//! # Quick start
22//!
23//! ```
24//! use matten::Tensor;
25//!
26//! let a = Tensor::new(vec![1.0, 2.0, 3.0, 4.0], &[2, 2]);
27//! assert_eq!(a.shape(), &[2, 2]);
28//! assert_eq!(a.ndim(), 2);
29//! println!("{a:?}");
30//! ```
31//!
32//! Boundary-style construction returns a [`Result`](std::result::Result) instead
33//! of panicking:
34//!
35//! ```
36//! use matten::{MattenError, Tensor};
37//!
38//! let bad = Tensor::try_new(vec![1.0, 2.0, 3.0], &[2, 2]);
39//! assert!(matches!(bad, Err(MattenError::Shape { .. })));
40//! ```
41//!
42//! # Panic zone vs Result zone
43//!
44//! `matten` splits its API into two error zones:
45//!
46//! - **Panic zone** — local, developer-authored convenience APIs (such as
47//!   [`Tensor::new`]) panic with an actionable message for fast PoC feedback.
48//! - **Result zone** — every external boundary (parsing, file I/O, user-driven
49//!   construction such as [`Tensor::try_new`]) returns [`MattenError`] and never
50//!   panics on ordinary invalid input.
51//!
52//! Errors are matched by variant (`matches!`), never by `==`: [`MattenError`]
53//! embeds [`std::io::Error`] and so derives only `Debug`.
54//!
55//! # Cargo features
56//!
57//! The default profile is convenient for PoC users:
58//!
59//! - `serde` *(default)* — `Serialize` / `Deserialize` for [`Tensor`].
60//! - `json` *(default, implies `serde`)* — `from_json` / `load_json`.
61//! - `csv` *(default)* — `from_csv` / `load_csv`.
62//! - `dynamic` — the Phase 2 heterogeneous `Element` engine (off by default).
63//!
64//! For the smallest dependency footprint, disable defaults and opt in:
65//!
66//! ```toml
67//! matten = { version = "0.16", default-features = false }
68//! ```
69
70#![forbid(unsafe_code)]
71
72// Public modules. The public surface is intentionally centered on `Tensor`,
73// `MattenError`, and `DataFormat`; storage, layout, and (future) `ops` modules
74// stay internal.
75//
76// Internal module map (each added with its owning milestone):
77//   shape       shape validation, strides, row-major index helpers (M1)
78//   convert     From/TryFrom impls and nested-row helpers (M2)
79//   ops/        element-wise + scalar operators and broadcasting (M3)
80//   reshape     reshape, flatten, transpose, swap_axes helpers (M4)
81//   slice       SliceSpec, SliceBuilder, execute_slice, slice_str (M4)
82//   math        sum/mean/min/max, axis reductions, dot, matmul (M7, here)
83//   ser         Serialize/Deserialize for Tensor
84//   parse/      JSON/CSV boundary parsers
85//   dynamic/    feature-gated `Element` engine (Phase 2)
86mod convert;
87#[cfg(feature = "dynamic")]
88mod dynamic;
89mod error;
90mod limits;
91mod math;
92mod ops;
93mod parse;
94mod reshape;
95mod ser;
96mod shape;
97mod slice;
98mod tensor;
99
100#[cfg(feature = "dynamic")]
101pub use crate::dynamic::Element;
102#[cfg(feature = "dynamic")]
103pub use crate::dynamic::NumericPolicy;
104pub use crate::error::{DataFormat, MattenError};
105pub use crate::limits::MattenLimits;
106pub use crate::slice::SliceBuilder;
107// Slice trait plumbing — public for the sealed-bound chain but hidden from docs.
108#[doc(hidden)]
109pub use crate::slice::{IntoSliceRange, SliceConvert, SliceSpecRepr};
110pub use crate::tensor::Tensor;
111
112// `Element` is the Phase 2 dynamic value type, exported under `dynamic`.
113
114#[cfg(test)]
115mod tests;