Skip to main content

dear_implot3d/plots/
mod.rs

1//! Modular plot types for ImPlot3D
2//!
3//! Builder-oriented API mirroring dear-implot's `plots` module.
4//! Validation helpers are implementation details and are not part of the public API:
5//!
6//! ```compile_fail
7//! use dear_implot3d::plots::{validate_lengths, validate_multiple, validate_nonempty};
8//! ```
9//!
10//! ```compile_fail
11//! use dear_implot3d::{validate_lengths, validate_multiple, validate_nonempty};
12//! ```
13
14pub mod image;
15pub mod line;
16pub mod mesh;
17pub mod quads;
18pub mod scatter;
19pub mod surface;
20pub mod triangles;
21
22pub use image::*;
23pub use line::*;
24pub use mesh::*;
25pub use quads::*;
26pub use scatter::*;
27pub use surface::*;
28pub use triangles::*;
29
30/// Errors that can occur during 3D plotting
31#[derive(Debug, Clone, PartialEq)]
32pub enum Plot3DError {
33    EmptyData,
34    DataLengthMismatch {
35        a: usize,
36        b: usize,
37        what: &'static str,
38    },
39    NotMultipleOf {
40        len: usize,
41        k: usize,
42        what: &'static str,
43    },
44    GridSizeMismatch {
45        x_count: usize,
46        y_count: usize,
47        expected: usize,
48        z_len: usize,
49    },
50    GridSizeOverflow {
51        x_count: usize,
52        y_count: usize,
53    },
54    GridPointCountOutOfRange {
55        x_count: usize,
56        y_count: usize,
57        point_count: usize,
58    },
59    StringConversion(&'static str),
60}
61
62impl std::fmt::Display for Plot3DError {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        match self {
65            Plot3DError::EmptyData => write!(f, "data is empty"),
66            Plot3DError::DataLengthMismatch { a, b, what } => {
67                write!(f, "length mismatch for {}: {} vs {}", what, a, b)
68            }
69            Plot3DError::NotMultipleOf { len, k, what } => {
70                write!(f, "length of {} = {} is not multiple of {}", what, len, k)
71            }
72            Plot3DError::GridSizeMismatch {
73                x_count,
74                y_count,
75                expected,
76                z_len,
77            } => write!(
78                f,
79                "grid mismatch: x={} y={} => expected z_len={}, got {}",
80                x_count, y_count, expected, z_len
81            ),
82            Plot3DError::GridSizeOverflow { x_count, y_count } => write!(
83                f,
84                "surface grid size overflow: x_count={} y_count={}",
85                x_count, y_count
86            ),
87            Plot3DError::GridPointCountOutOfRange {
88                x_count,
89                y_count,
90                point_count,
91            } => write!(
92                f,
93                "surface grid x_count={} y_count={} has {} points, exceeding ImPlot3D's i32 range",
94                x_count, y_count, point_count
95            ),
96            Plot3DError::StringConversion(what) => write!(f, "string conversion error: {}", what),
97        }
98    }
99}
100
101impl std::error::Error for Plot3DError {}
102
103/// Common trait for 3D plot elements
104pub trait Plot3D {
105    fn label(&self) -> &str;
106    fn try_plot(&self, ui: &crate::Plot3DUi<'_>) -> Result<(), Plot3DError>;
107    fn plot(&self, ui: &crate::Plot3DUi<'_>) {
108        let _ = self.try_plot(ui);
109    }
110}
111
112#[inline]
113pub(crate) fn validate_nonempty<T>(a: &[T]) -> Result<(), Plot3DError> {
114    if a.is_empty() {
115        Err(Plot3DError::EmptyData)
116    } else {
117        Ok(())
118    }
119}
120
121#[inline]
122pub(crate) fn validate_lengths<T, U>(
123    a: &[T],
124    b: &[U],
125    what: &'static str,
126) -> Result<(), Plot3DError> {
127    if a.len() != b.len() {
128        Err(Plot3DError::DataLengthMismatch {
129            a: a.len(),
130            b: b.len(),
131            what,
132        })
133    } else {
134        Ok(())
135    }
136}
137
138#[inline]
139pub(crate) fn validate_multiple(
140    len: usize,
141    k: usize,
142    what: &'static str,
143) -> Result<(), Plot3DError> {
144    if len % k != 0 {
145        Err(Plot3DError::NotMultipleOf { len, k, what })
146    } else {
147        Ok(())
148    }
149}