Skip to main content

mindat_rs/models/
occurrences.rs

1//! Occurrence types for the Mindat API.
2//!
3//! Occurrences (`/occurrences/`) are individual mineral-at-locality entries,
4//! while occurrence statistics (`/occurrences-statistics/`) aggregate them per
5//! mineral/locality pair.
6
7use serde::{Deserialize, Serialize};
8
9use super::serde_helpers::{deserialize_i64, deserialize_optional_i32, deserialize_optional_i64};
10
11/// A single mineral-at-locality occurrence entry (`/occurrences/`).
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct Occurrence {
14    /// Occurrence (locentry) ID.
15    #[serde(deserialize_with = "deserialize_i64")]
16    pub id: i64,
17    /// Mineral (geomaterial) ID.
18    #[serde(default, deserialize_with = "deserialize_optional_i64")]
19    pub min: Option<i64>,
20    /// Locality ID.
21    #[serde(default, deserialize_with = "deserialize_optional_i64")]
22    pub loc: Option<i64>,
23    /// Type-locality flag/value.
24    #[serde(default)]
25    pub typeloc: Option<serde_json::Value>,
26    /// Questioned flag/value.
27    #[serde(default)]
28    pub questioned: Option<serde_json::Value>,
29    /// Reference ID.
30    #[serde(default, deserialize_with = "deserialize_optional_i64")]
31    pub refid: Option<i64>,
32    /// Description.
33    #[serde(default)]
34    pub description: Option<String>,
35    /// Quality.
36    #[serde(default)]
37    pub quality: Option<serde_json::Value>,
38    /// Rarity.
39    #[serde(default)]
40    pub rarity: Option<serde_json::Value>,
41    /// Habit.
42    #[serde(default)]
43    pub habit: Option<String>,
44    /// Fluorescence.
45    #[serde(default)]
46    pub fluorescence: Option<String>,
47    /// Colour.
48    #[serde(default)]
49    pub colour: Option<String>,
50    /// Confirmation methods.
51    #[serde(default)]
52    pub cfmethods: Option<String>,
53    /// Confirmation reference.
54    #[serde(default)]
55    pub cfref: Option<String>,
56    /// Reference text.
57    #[serde(default)]
58    pub reftxt: Option<String>,
59    /// Date modified.
60    #[serde(default)]
61    pub datemodify: Option<String>,
62    /// Specimen display info.
63    #[serde(default)]
64    pub specdisp: Option<String>,
65    /// Locality reversed-text description.
66    #[serde(default)]
67    pub lorevtxtd: Option<String>,
68}
69
70/// Aggregated occurrence statistics for a mineral/locality pair
71/// (`/occurrences-statistics/`).
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct OccurrenceStatistics {
74    /// Locality ID.
75    #[serde(default, deserialize_with = "deserialize_optional_i64")]
76    pub lstm_loc: Option<i64>,
77    /// Mineral (geomaterial) ID.
78    #[serde(default, deserialize_with = "deserialize_optional_i64")]
79    pub lstm_min: Option<i64>,
80    /// Number of localities.
81    #[serde(default, deserialize_with = "deserialize_optional_i64")]
82    pub lstm_numlocs: Option<i64>,
83    /// IMA-variety flag.
84    #[serde(default, deserialize_with = "deserialize_optional_i32")]
85    pub lstm_imavar: Option<i32>,
86    /// IMA-real flag.
87    #[serde(default, deserialize_with = "deserialize_optional_i32")]
88    pub lstm_imareal: Option<i32>,
89    /// Photo count.
90    #[serde(default, deserialize_with = "deserialize_optional_i64")]
91    pub lstm_photocount: Option<i64>,
92    /// Is-locality-entry flag.
93    #[serde(default, deserialize_with = "deserialize_optional_i64")]
94    pub lstm_islocentry: Option<i64>,
95    /// Type-locality value.
96    #[serde(default, deserialize_with = "deserialize_optional_i32")]
97    pub lstm_typeloc: Option<i32>,
98    /// Maximum quality.
99    #[serde(default, deserialize_with = "deserialize_optional_i32")]
100    pub lstm_qualitymax: Option<i32>,
101    /// Questioned flag.
102    #[serde(default, deserialize_with = "deserialize_optional_i32")]
103    pub lstm_questioned: Option<i32>,
104    /// Sub-localities list.
105    #[serde(default)]
106    pub lstm_sublocslist: Option<String>,
107    /// Display name.
108    #[serde(default)]
109    pub lstm_display_name: Option<String>,
110    /// Last-changed timestamp.
111    #[serde(default)]
112    pub lstm_changed: Option<String>,
113}
114
115/// Builder for `/occurrences/` query parameters.
116#[derive(Debug, Clone, Default)]
117pub struct OccurrencesQuery {
118    /// Filter by mineral (geomaterial) ID.
119    pub min: Option<i64>,
120    /// Filter by locality ID.
121    pub loc: Option<i64>,
122    /// Filter by colour.
123    pub colour: Option<String>,
124    /// Filter by habit.
125    pub habit: Option<String>,
126    /// Filter by fluorescence.
127    pub fluorescence: Option<String>,
128    /// Filter by description.
129    pub description: Option<String>,
130    /// Modified after datetime.
131    pub datemodify_after: Option<String>,
132    /// Modified before datetime.
133    pub datemodify_before: Option<String>,
134    /// Ordering field.
135    pub ordering: Option<String>,
136    /// Fields to include.
137    pub fields: Option<String>,
138    /// Fields to omit.
139    pub omit: Option<String>,
140    /// Page number.
141    pub page: Option<i32>,
142    /// Page size.
143    pub page_size: Option<i32>,
144}
145
146impl OccurrencesQuery {
147    /// Create a new empty query.
148    pub fn new() -> Self {
149        Self::default()
150    }
151
152    /// Filter to occurrences of a given mineral.
153    pub fn mineral(mut self, mineral_id: i64) -> Self {
154        self.min = Some(mineral_id);
155        self
156    }
157
158    /// Filter to occurrences at a given locality.
159    pub fn locality(mut self, locality_id: i64) -> Self {
160        self.loc = Some(locality_id);
161        self
162    }
163
164    /// Set page number.
165    pub fn page(mut self, page: i32) -> Self {
166        self.page = Some(page);
167        self
168    }
169
170    /// Set page size.
171    pub fn page_size(mut self, size: i32) -> Self {
172        self.page_size = Some(size);
173        self
174    }
175}
176
177/// Builder for `/occurrences-statistics/` query parameters.
178#[derive(Debug, Clone, Default)]
179pub struct OccurrenceStatisticsQuery {
180    /// Filter by mineral (geomaterial) ID.
181    pub lstm_min: Option<i64>,
182    /// Filter by locality ID.
183    pub lstm_loc: Option<i64>,
184    /// Minimum photo count.
185    pub photocount_min: Option<i64>,
186    /// Maximum photo count.
187    pub photocount_max: Option<i64>,
188    /// Ordering field.
189    pub ordering: Option<String>,
190    /// Page number.
191    pub page: Option<i32>,
192    /// Page size.
193    pub page_size: Option<i32>,
194}
195
196impl OccurrenceStatisticsQuery {
197    /// Create a new empty query.
198    pub fn new() -> Self {
199        Self::default()
200    }
201
202    /// Filter to statistics for a given mineral.
203    pub fn mineral(mut self, mineral_id: i64) -> Self {
204        self.lstm_min = Some(mineral_id);
205        self
206    }
207
208    /// Filter to statistics for a given locality.
209    pub fn locality(mut self, locality_id: i64) -> Self {
210        self.lstm_loc = Some(locality_id);
211        self
212    }
213
214    /// Set page number.
215    pub fn page(mut self, page: i32) -> Self {
216        self.page = Some(page);
217        self
218    }
219
220    /// Set page size.
221    pub fn page_size(mut self, size: i32) -> Self {
222        self.page_size = Some(size);
223        self
224    }
225}