mindat_rs/models/
geomaterials.rs

1//! Geomaterial types for the Mindat API.
2
3use serde::{Deserialize, Serialize};
4
5use super::common::{MinStats, Relation};
6use super::enums::*;
7use super::serde_helpers::{
8    deserialize_optional_f64, deserialize_optional_i32, deserialize_optional_u32,
9    deserialize_optional_vec, deserialize_optional_vec_i32, deserialize_optional_vec_string,
10};
11
12/// A geomaterial (mineral, variety, synonym, rock, etc.) from the Mindat database.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Geomaterial {
15    /// Mindat ID.
16    pub id: i32,
17    /// Long ID string.
18    #[serde(default)]
19    pub longid: Option<String>,
20    /// GUID.
21    #[serde(default)]
22    pub guid: Option<String>,
23    /// Name of the geomaterial.
24    pub name: Option<String>,
25    /// Last update time.
26    #[serde(default)]
27    pub updttime: Option<String>,
28    /// Mindat chemical formula.
29    #[serde(default)]
30    pub mindat_formula: Option<String>,
31    /// Notes on the Mindat formula.
32    #[serde(default)]
33    pub mindat_formula_note: Option<String>,
34    /// IMA-approved chemical formula.
35    #[serde(default)]
36    pub ima_formula: Option<String>,
37    /// IMA status values.
38    #[serde(default, deserialize_with = "deserialize_optional_vec_string")]
39    pub ima_status: Option<Vec<String>>,
40    /// IMA notes.
41    #[serde(default, deserialize_with = "deserialize_optional_vec_string")]
42    pub ima_notes: Option<Vec<String>>,
43    /// Variety of (geomaterial ID).
44    #[serde(default, deserialize_with = "deserialize_optional_i32")]
45    pub varietyof: Option<i32>,
46    /// Synonym of (geomaterial ID).
47    #[serde(default, deserialize_with = "deserialize_optional_i32")]
48    pub synid: Option<i32>,
49    /// Polytype of (geomaterial ID).
50    #[serde(default, deserialize_with = "deserialize_optional_i32")]
51    pub polytypeof: Option<i32>,
52    /// Group ID (member of).
53    #[serde(default, deserialize_with = "deserialize_optional_i32")]
54    pub groupid: Option<i32>,
55    /// Entry type (0=mineral, 1=synonym, 2=variety, etc.).
56    #[serde(default, deserialize_with = "deserialize_optional_i32")]
57    pub entrytype: Option<i32>,
58    /// Entry type as text.
59    #[serde(default)]
60    pub entrytype_text: Option<String>,
61    /// Short description.
62    #[serde(default)]
63    pub description_short: Option<String>,
64    /// Common impurities.
65    #[serde(default)]
66    pub impurities: Option<String>,
67    /// Elements present.
68    #[serde(default, deserialize_with = "deserialize_optional_vec_string")]
69    pub elements: Option<Vec<String>>,
70    /// Significant elements.
71    #[serde(default, deserialize_with = "deserialize_optional_vec_string")]
72    pub sigelements: Option<Vec<String>>,
73    /// Key elements (important for mining).
74    #[serde(default, deserialize_with = "deserialize_optional_vec_string")]
75    pub key_elements: Option<Vec<String>>,
76    /// Type locality form.
77    #[serde(default)]
78    pub tlform: Option<String>,
79    /// HEY index.
80    #[serde(default)]
81    pub cim: Option<String>,
82    /// Type locality occurrence.
83    #[serde(default)]
84    pub occurrence: Option<String>,
85    /// Other occurrences.
86    #[serde(default)]
87    pub otheroccurrence: Option<String>,
88    /// Industrial uses.
89    #[serde(default)]
90    pub industrial: Option<String>,
91    /// Discovery year.
92    #[serde(default)]
93    pub discovery_year: Option<String>,
94    /// Approval year.
95    #[serde(default, deserialize_with = "deserialize_optional_u32")]
96    pub approval_year: Option<u32>,
97    /// Publication year.
98    #[serde(default, deserialize_with = "deserialize_optional_u32")]
99    pub publication_year: Option<u32>,
100    /// IMA history.
101    #[serde(default)]
102    pub ima_history: Option<String>,
103    /// Transparency (diapheny).
104    #[serde(default)]
105    pub diapheny: Option<String>,
106    /// Cleavage description.
107    #[serde(default)]
108    pub cleavage: Option<String>,
109    /// Cleavage type.
110    #[serde(default)]
111    pub cleavagetype: Option<String>,
112    /// Parting.
113    #[serde(default)]
114    pub parting: Option<String>,
115    /// Tenacity.
116    #[serde(default)]
117    pub tenacity: Option<String>,
118    /// Colour description.
119    #[serde(default)]
120    pub colour: Option<String>,
121    /// Metamict flag.
122    #[serde(default, deserialize_with = "deserialize_optional_i32")]
123    pub csmetamict: Option<i32>,
124    /// Optical extinction direction.
125    #[serde(default)]
126    pub opticalextinction: Option<String>,
127    /// Minimum Mohs hardness.
128    #[serde(default, deserialize_with = "deserialize_optional_f64")]
129    pub hmin: Option<f64>,
130    /// Maximum Mohs hardness.
131    #[serde(default, deserialize_with = "deserialize_optional_f64")]
132    pub hmax: Option<f64>,
133    /// Hardness type.
134    #[serde(default, deserialize_with = "deserialize_optional_i32")]
135    pub hardtype: Option<i32>,
136    /// Vickers hardness minimum.
137    #[serde(default)]
138    pub vhnmin: Option<String>,
139    /// Vickers hardness maximum.
140    #[serde(default)]
141    pub vhnmax: Option<String>,
142    /// Vickers hardness error.
143    #[serde(default, deserialize_with = "deserialize_optional_i32")]
144    pub vhnerror: Option<i32>,
145    /// Vickers hardness weight.
146    #[serde(default, deserialize_with = "deserialize_optional_i32")]
147    pub vhng: Option<i32>,
148    /// Vickers hardness time.
149    #[serde(default, deserialize_with = "deserialize_optional_i32")]
150    pub vhns: Option<i32>,
151    /// Luminescence.
152    #[serde(default)]
153    pub luminescence: Option<String>,
154    /// Lustre description.
155    #[serde(default)]
156    pub lustre: Option<String>,
157    /// Lustre type.
158    #[serde(default)]
159    pub lustretype: Option<String>,
160    /// About name reference.
161    #[serde(default)]
162    pub aboutname: Option<String>,
163    /// Other information.
164    #[serde(default)]
165    pub other: Option<String>,
166    /// Streak colour.
167    #[serde(default)]
168    pub streak: Option<String>,
169    /// Crystal system.
170    #[serde(default)]
171    pub csystem: Option<String>,
172    /// Crystal class (point group ID).
173    #[serde(default, deserialize_with = "deserialize_optional_i32")]
174    pub cclass: Option<i32>,
175    /// Space group ID.
176    #[serde(default, deserialize_with = "deserialize_optional_i32")]
177    pub spacegroup: Option<i32>,
178    /// Space group setting.
179    #[serde(default)]
180    pub spacegroupset: Option<String>,
181    /// Unit cell a.
182    #[serde(default)]
183    pub a: Option<String>,
184    /// Unit cell b.
185    #[serde(default)]
186    pub b: Option<String>,
187    /// Unit cell c.
188    #[serde(default)]
189    pub c: Option<String>,
190    /// Unit cell alpha.
191    #[serde(default)]
192    pub alpha: Option<String>,
193    /// Unit cell beta.
194    #[serde(default)]
195    pub beta: Option<String>,
196    /// Unit cell gamma.
197    #[serde(default)]
198    pub gamma: Option<String>,
199    /// Unit cell volume.
200    #[serde(default, deserialize_with = "deserialize_optional_f64")]
201    pub va3: Option<f64>,
202    /// Z value.
203    #[serde(default, deserialize_with = "deserialize_optional_i32")]
204    pub z: Option<i32>,
205    /// Measured density minimum.
206    #[serde(default)]
207    pub dmeas: Option<String>,
208    /// Measured density maximum.
209    #[serde(default)]
210    pub dmeas2: Option<String>,
211    /// Calculated density.
212    #[serde(default)]
213    pub dcalc: Option<String>,
214    /// Fracture type.
215    #[serde(default)]
216    pub fracturetype: Option<String>,
217    /// Morphology.
218    #[serde(default)]
219    pub morphology: Option<String>,
220    /// Twinning.
221    #[serde(default)]
222    pub twinning: Option<String>,
223    /// Epitaxy description.
224    #[serde(default)]
225    pub epitaxidescription: Option<String>,
226    /// Optical type.
227    #[serde(default)]
228    pub opticaltype: Option<String>,
229    /// Optical sign.
230    #[serde(default)]
231    pub opticalsign: Option<String>,
232    /// Refractive index alpha.
233    #[serde(default)]
234    pub opticalalpha: Option<String>,
235    /// Refractive index beta.
236    #[serde(default)]
237    pub opticalbeta: Option<String>,
238    /// Refractive index gamma.
239    #[serde(default)]
240    pub opticalgamma: Option<String>,
241    /// Refractive index omega.
242    #[serde(default)]
243    pub opticalomega: Option<String>,
244    /// Refractive index epsilon.
245    #[serde(default)]
246    pub opticalepsilon: Option<String>,
247    /// Refractive index n.
248    #[serde(default)]
249    pub opticaln: Option<String>,
250    /// 2V calculated.
251    #[serde(default)]
252    pub optical2vcalc: Option<String>,
253    /// 2V measured.
254    #[serde(default)]
255    pub optical2vmeasured: Option<String>,
256    /// Optical dispersion.
257    #[serde(default)]
258    pub opticaldispersion: Option<String>,
259    /// Pleochroism.
260    #[serde(default)]
261    pub opticalpleochroism: Option<String>,
262    /// Pleochroism description.
263    #[serde(default)]
264    pub opticalpleochorismdesc: Option<String>,
265    /// Birefringence.
266    #[serde(default)]
267    pub opticalbirefringence: Option<String>,
268    /// Optical comments.
269    #[serde(default)]
270    pub opticalcomments: Option<String>,
271    /// Colour in reflected light.
272    #[serde(default)]
273    pub opticalcolour: Option<String>,
274    /// Internal reflections.
275    #[serde(default)]
276    pub opticalinternal: Option<String>,
277    /// Optical tropic.
278    #[serde(default)]
279    pub opticaltropic: Option<String>,
280    /// Anisotropism.
281    #[serde(default)]
282    pub opticalanisotropism: Option<String>,
283    /// Bireflectance.
284    #[serde(default)]
285    pub opticalbireflectance: Option<String>,
286    /// Optical reflectivity.
287    #[serde(default)]
288    pub opticalr: Option<String>,
289    /// Refractive index minimum.
290    #[serde(default, deserialize_with = "deserialize_optional_f64")]
291    pub rimin: Option<f64>,
292    /// Refractive index maximum.
293    #[serde(default, deserialize_with = "deserialize_optional_f64")]
294    pub rimax: Option<f64>,
295    /// UV fluorescence.
296    #[serde(default)]
297    pub uv: Option<String>,
298    /// IR spectrum.
299    #[serde(default)]
300    pub ir: Option<String>,
301    /// Magnetism.
302    #[serde(default)]
303    pub magnetism: Option<String>,
304    /// Type specimen storage location.
305    #[serde(default)]
306    pub type_specimen_store: Option<String>,
307    /// IMA shortcode.
308    #[serde(default)]
309    pub shortcode_ima: Option<String>,
310    /// Strunz classification (10th ed) parts.
311    #[serde(default)]
312    pub strunz10ed1: Option<String>,
313    #[serde(default)]
314    pub strunz10ed2: Option<String>,
315    #[serde(default)]
316    pub strunz10ed3: Option<String>,
317    #[serde(default)]
318    pub strunz10ed4: Option<String>,
319    /// Dana classification (8th ed) parts.
320    #[serde(default)]
321    pub dana8ed1: Option<String>,
322    #[serde(default)]
323    pub dana8ed2: Option<String>,
324    #[serde(default)]
325    pub dana8ed3: Option<String>,
326    #[serde(default)]
327    pub dana8ed4: Option<String>,
328    /// Thermal behaviour.
329    #[serde(default)]
330    pub thermalbehaviour: Option<String>,
331    /// Electrical properties.
332    #[serde(default)]
333    pub electrical: Option<String>,
334    /// Rock parent ID.
335    #[serde(default, deserialize_with = "deserialize_optional_i32")]
336    pub rock_parent: Option<i32>,
337    /// Rock parent 2 ID.
338    #[serde(default, deserialize_with = "deserialize_optional_i32")]
339    pub rock_parent2: Option<i32>,
340    /// Rock root ID.
341    #[serde(default, deserialize_with = "deserialize_optional_i32")]
342    pub rock_root: Option<i32>,
343    /// Rock BGS code.
344    #[serde(default)]
345    pub rock_bgs_code: Option<String>,
346    /// Meteoritical code.
347    #[serde(default)]
348    pub meteoritical_code: Option<String>,
349    /// Weighting.
350    #[serde(default, deserialize_with = "deserialize_optional_i32")]
351    pub weighting: Option<i32>,
352    /// Relations to other geomaterials.
353    #[serde(default, deserialize_with = "deserialize_optional_vec")]
354    pub relations: Option<Vec<Relation>>,
355    /// Mineral statistics.
356    #[serde(default)]
357    pub minstats: Option<MinStats>,
358    /// Localities where found.
359    #[serde(default, deserialize_with = "deserialize_optional_vec_i32")]
360    pub locality: Option<Vec<i32>>,
361    /// Type localities.
362    #[serde(default, deserialize_with = "deserialize_optional_vec_i32")]
363    pub type_localities: Option<Vec<i32>>,
364}
365
366/// Builder for geomaterial query parameters.
367#[derive(Debug, Clone, Default)]
368pub struct GeomaterialsQuery {
369    /// Name filter (supports wildcards * and _).
370    pub name: Option<String>,
371    /// Search query.
372    pub q: Option<String>,
373    /// IMA approved only.
374    pub ima: Option<bool>,
375    /// IMA status filter.
376    pub ima_status: Option<Vec<ImaStatus>>,
377    /// IMA notes filter.
378    pub ima_notes: Option<Vec<ImaNotes>>,
379    /// Entry types filter.
380    pub entrytype: Option<Vec<u8>>,
381    /// Include elements (comma-separated).
382    pub elements_inc: Option<String>,
383    /// Exclude elements (comma-separated).
384    pub elements_exc: Option<String>,
385    /// Crystal system filter.
386    pub crystal_system: Option<Vec<CrystalSystem>>,
387    /// Cleavage type filter.
388    pub cleavagetype: Option<Vec<CleavageType>>,
389    /// Fracture type filter.
390    pub fracturetype: Option<Vec<FractureType>>,
391    /// Lustre type filter.
392    pub lustretype: Option<Vec<LustreType>>,
393    /// Diapheny (transparency) filter.
394    pub diapheny: Option<Vec<Diapheny>>,
395    /// Tenacity filter.
396    pub tenacity: Option<Vec<Tenacity>>,
397    /// Colour filter.
398    pub colour: Option<String>,
399    /// Streak filter.
400    pub streak: Option<String>,
401    /// Optical type filter.
402    pub opticaltype: Option<OpticalType>,
403    /// Optical sign filter.
404    pub opticalsign: Option<OpticalSign>,
405    /// Hardness minimum (Mohs).
406    pub hardness_min: Option<f32>,
407    /// Hardness maximum (Mohs).
408    pub hardness_max: Option<f32>,
409    /// Density minimum.
410    pub density_min: Option<f64>,
411    /// Density maximum.
412    pub density_max: Option<f64>,
413    /// Refractive index minimum.
414    pub ri_min: Option<f32>,
415    /// Refractive index maximum.
416    pub ri_max: Option<f32>,
417    /// Birefringence minimum.
418    pub bi_min: Option<String>,
419    /// Birefringence maximum.
420    pub bi_max: Option<String>,
421    /// 2V minimum.
422    pub optical2v_min: Option<String>,
423    /// 2V maximum.
424    pub optical2v_max: Option<String>,
425    /// Variety of (geomaterial ID).
426    pub varietyof: Option<i32>,
427    /// Synonym of (geomaterial ID).
428    pub synid: Option<i32>,
429    /// Polytype of (geomaterial ID).
430    pub polytypeof: Option<i32>,
431    /// Group ID.
432    pub groupid: Option<i32>,
433    /// Filter by IDs.
434    pub id_in: Option<Vec<i32>>,
435    /// Include non-UTF names.
436    pub non_utf: Option<bool>,
437    /// Meteoritical code filter.
438    pub meteoritical_code: Option<String>,
439    /// Meteoritical code exists.
440    pub meteoritical_code_exists: Option<bool>,
441    /// Updated after datetime.
442    pub updated_at: Option<String>,
443    /// Fields to include.
444    pub fields: Option<String>,
445    /// Fields to omit.
446    pub omit: Option<String>,
447    /// Fields to expand.
448    pub expand: Option<Vec<String>>,
449    /// Ordering.
450    pub ordering: Option<GeomaterialsOrdering>,
451    /// Page number.
452    pub page: Option<i32>,
453    /// Page size.
454    pub page_size: Option<i32>,
455}
456
457impl GeomaterialsQuery {
458    /// Create a new empty query.
459    pub fn new() -> Self {
460        Self::default()
461    }
462
463    /// Filter by name (supports * and _ wildcards).
464    pub fn name(mut self, name: impl Into<String>) -> Self {
465        self.name = Some(name.into());
466        self
467    }
468
469    /// Search query.
470    pub fn search(mut self, q: impl Into<String>) -> Self {
471        self.q = Some(q.into());
472        self
473    }
474
475    /// Filter to IMA-approved minerals only.
476    pub fn ima_approved(mut self, approved: bool) -> Self {
477        self.ima = Some(approved);
478        self
479    }
480
481    /// Filter by entry type.
482    pub fn entry_types(mut self, types: Vec<u8>) -> Self {
483        self.entrytype = Some(types);
484        self
485    }
486
487    /// Filter by included elements.
488    pub fn with_elements(mut self, elements: impl Into<String>) -> Self {
489        self.elements_inc = Some(elements.into());
490        self
491    }
492
493    /// Filter by excluded elements.
494    pub fn without_elements(mut self, elements: impl Into<String>) -> Self {
495        self.elements_exc = Some(elements.into());
496        self
497    }
498
499    /// Filter by crystal system.
500    pub fn crystal_systems(mut self, systems: Vec<CrystalSystem>) -> Self {
501        self.crystal_system = Some(systems);
502        self
503    }
504
505    /// Filter by hardness range.
506    pub fn hardness_range(mut self, min: f32, max: f32) -> Self {
507        self.hardness_min = Some(min);
508        self.hardness_max = Some(max);
509        self
510    }
511
512    /// Filter by density range.
513    pub fn density_range(mut self, min: f64, max: f64) -> Self {
514        self.density_min = Some(min);
515        self.density_max = Some(max);
516        self
517    }
518
519    /// Select specific fields.
520    pub fn select_fields(mut self, fields: impl Into<String>) -> Self {
521        self.fields = Some(fields.into());
522        self
523    }
524
525    /// Omit specific fields.
526    pub fn omit_fields(mut self, fields: impl Into<String>) -> Self {
527        self.omit = Some(fields.into());
528        self
529    }
530
531    /// Expand related fields.
532    pub fn expand_fields(mut self, fields: Vec<String>) -> Self {
533        self.expand = Some(fields);
534        self
535    }
536
537    /// Set ordering.
538    pub fn order_by(mut self, ordering: GeomaterialsOrdering) -> Self {
539        self.ordering = Some(ordering);
540        self
541    }
542
543    /// Set page number.
544    pub fn page(mut self, page: i32) -> Self {
545        self.page = Some(page);
546        self
547    }
548
549    /// Set page size.
550    pub fn page_size(mut self, size: i32) -> Self {
551        self.page_size = Some(size);
552        self
553    }
554}