las/feature.rs
1//! Programmatically determine whether a las version supports a feature.
2//!
3//! Features are structures that implement the [Feature] trait. The most common
4//! way to use features is via [Version::supports] or
5//! [Version::verify_support_for]:
6//!
7//! ```
8//! use las::feature::Waveforms;
9//! use las::{Version, Error};
10//!
11//! let las_1_2 = Version::new(1, 2);
12//! assert!(!las_1_2.supports::<Waveforms>());
13//! assert!(las_1_2.verify_support_for::<Waveforms>().is_err());
14//!
15//! let las_1_4 = Version::new(1, 4);
16//! assert!(las_1_4.supports::<Waveforms>());
17//! assert!(las_1_4.verify_support_for::<Waveforms>().is_ok());
18//! ```
19
20use crate::Version;
21
22const MAJOR: u8 = 1;
23
24/// A trait implemented by each feature.
25pub trait Feature {
26 /// Is this feature supported by this version?
27 ///
28 /// # Examples
29 ///
30 /// ```
31 /// use las::feature::{Waveforms, Feature};
32 /// use las::Version;
33 /// assert!(!Waveforms::is_supported_by(Version::new(1, 2)));
34 /// assert!(Waveforms::is_supported_by(Version::new(1, 4)));
35 /// ```
36 fn is_supported_by(version: Version) -> bool;
37
38 /// Returns the name of this feature.
39 ///
40 /// # Examples
41 ///
42 /// ```
43 /// use las::feature::{Waveforms, Feature};
44 /// assert_eq!("Waveforms", Waveforms::name());
45 /// ```
46 fn name() -> &'static str;
47}
48
49macro_rules! features {
50 ( $(
51 $(#[$meta:meta])*
52 $name:ident ($($versions:expr_2021),+);
53 )+
54 ) => {
55 $(
56 $(#[$meta])*
57 #[derive(Clone, Copy, Debug)]
58 pub struct $name {}
59
60 impl Feature for $name {
61 fn is_supported_by(version: Version) -> bool {
62 vec![$($versions),+]
63 .into_iter()
64 .map(|minor| Version::new(MAJOR, minor))
65 .any(|v| version == v)
66 }
67
68 fn name() -> &'static str {
69 stringify!($name)
70 }
71 }
72 )+
73 }
74}
75
76features! {
77 /// Does the header allow a file source id, or is that field reserved?
78 FileSourceId(1, 2, 3, 4);
79 /// Is there a bit flag to set the type of time value in each point?
80 GpsStandardTime(2, 3, 4);
81 /// Does this file support waveforms?
82 Waveforms(3, 4);
83 /// Is there a bit flag to indicate synthetic return numbers?
84 SyntheticReturnNumbers(3, 4);
85 /// Does this file support 64-bit point counts?
86 LargeFiles(4);
87 /// Does this file support extended variable length records?
88 Evlrs(4);
89}