Skip to main content

boring_parser/
boring_structs_400.rs

1use serde::{Deserialize, Serialize};
2
3// v3.00とv2.10の構造体を流用
4use crate::boring_structs_210::*;
5use crate::boring_structs_300::*;
6use crate::classification::{ClassificationInfo, Constituent, RockGroupCode, RockGroupInfo};
7use crate::types::FreeInfo;
8
9// ============================================================================
10// ルート構造体 - v4.00で基礎情報が追加
11// ============================================================================
12
13#[derive(Debug, Serialize, Deserialize)]
14#[serde(rename = "ボーリング情報")]
15pub struct Boring400 {
16    #[serde(rename = "@DTD_version")]
17    pub dtd_version: Option<String>,
18    #[serde(rename = "基礎情報")]
19    pub foundation_info: FoundationInfo400,
20    #[serde(rename = "標題情報")]
21    pub title: Title400,
22    #[serde(rename = "コア情報")]
23    pub core: Core400,
24}
25
26// ============================================================================
27// 基礎情報 - v4.00で新規追加
28// ============================================================================
29
30#[derive(Debug, Serialize, Deserialize)]
31pub struct FoundationInfo400 {
32    #[serde(default, rename = "適用規格")]
33    pub applicable_standards: Vec<String>,
34    #[serde(rename = "公開フラグ")]
35    pub public_flag: PublicFlag400,
36}
37
38#[derive(Debug, Serialize, Deserialize)]
39pub struct PublicFlag400 {
40    #[serde(rename = "公開フラグ_コード")]
41    pub code: Option<String>,
42    #[serde(default, rename = "公開フラグ_備考")]
43    pub remarks: Option<String>,
44}
45
46// ============================================================================
47// 標題情報 - v4.00でハンマー落下用具とN値記録用具が削除
48// ============================================================================
49
50#[derive(Debug, Serialize, Deserialize)]
51pub struct Title400 {
52    #[serde(rename = "調査基本情報")]
53    pub basic_info: BasicSurvey300, // v3.00を流用
54    #[serde(rename = "経度緯度情報")]
55    pub longitude_latitude: LngLat210, // v2.10を流用
56    #[serde(default, rename = "ローカル座標")]
57    pub local_coordinates: Vec<LocalCoordinate210>, // v2.10を流用
58    #[serde(rename = "調査位置")]
59    pub survey_position: SurveyPosition210, // v2.10を流用
60    #[serde(rename = "発注機関")]
61    pub order_institution: OrderInstitution210, // v2.10を流用
62    #[serde(rename = "調査期間")]
63    pub survey_period: SurveyPeriod210, // v2.10を流用
64    #[serde(rename = "調査会社")]
65    pub survey_company: SurveyCompany400, // v4.00で拡張(登録番号追加)
66    #[serde(rename = "ボーリング基本情報")]
67    pub boring_basic_info: BoringBasicInfo400, // v4.00でフィールド名変更
68    #[serde(rename = "試錐機")]
69    pub drilling_machine: DrillingMachine210, // v2.10を流用
70    #[serde(rename = "エンジン")]
71    pub engine: Engine210, // v2.10を流用
72    // v4.00で削除: ハンマー落下用具、N値記録用具
73    #[serde(rename = "ポンプ")]
74    pub pump: Pump210, // v2.10を流用
75    #[serde(default, rename = "櫓種類")]
76    pub tower_type: Option<TowerType210>, // v2.10を流用
77}
78
79// ============================================================================
80// 調査会社 - v4.00で地質調査技士登録番号等を追加
81// ============================================================================
82
83#[derive(Debug, Serialize, Deserialize)]
84pub struct SurveyCompany400 {
85    #[serde(rename = "調査会社_名称")]
86    pub name: Option<String>,
87    #[serde(rename = "調査会社_TEL")]
88    pub tel: Option<String>,
89    #[serde(rename = "調査会社_主任技師_氏名")]
90    pub chief_engineer_name: Option<String>,
91    #[serde(default, rename = "調査会社_主任技師_地質調査技士登録番号")]
92    pub chief_engineer_registration_number: Option<String>,
93    #[serde(rename = "調査会社_現場代理人_氏名")]
94    pub site_agent_name: Option<String>,
95    #[serde(default, rename = "調査会社_現場代理人_地質調査技士登録番号")]
96    pub site_agent_registration_number: Option<String>,
97    #[serde(rename = "調査会社_コア鑑定者_氏名")]
98    pub core_appraiser_name: Option<String>,
99    #[serde(default, rename = "調査会社_コア鑑定者_地質調査技士登録番号")]
100    pub core_appraiser_registration_number: Option<String>,
101    #[serde(rename = "調査会社_ボーリング責任者_氏名")]
102    pub boring_supervisor_name: Option<String>,
103    #[serde(default, rename = "調査会社_ボーリング責任者_地質調査技士登録番号")]
104    pub boring_supervisor_registration_number: Option<String>,
105    #[serde(default, rename = "調査会社_電子納品管理者_氏名")]
106    pub electronic_delivery_manager_name: Option<String>,
107    #[serde(default, rename = "調査会社_電子納品管理者_地質情報管理士登録番号")]
108    pub electronic_delivery_manager_registration_number: Option<String>,
109}
110
111// ============================================================================
112// ボーリング基本情報 - v4.00でフィールド名変更
113// 総掘進長→総削孔長、掘進角度→角度、掘進方向→方位
114// ============================================================================
115
116#[derive(Debug, Serialize, Deserialize)]
117pub struct BoringBasicInfo400 {
118    #[serde(rename = "孔口標高")]
119    pub surface_elevation: Option<String>,
120    #[serde(rename = "総削孔長")] // v3.00: 総掘進長
121    pub total_drilling_length: Option<String>,
122    #[serde(rename = "柱状図様式")]
123    pub columnar_diagram_format: Option<String>,
124    #[serde(default, rename = "角度")] // v3.00: 掘進角度
125    pub angle: Option<String>,
126    #[serde(default, rename = "方位")] // v3.00: 掘進方向
127    pub azimuth: Option<String>,
128    #[serde(default, rename = "地盤勾配")]
129    pub ground_slope: Option<String>,
130}
131
132// ============================================================================
133// コア情報 - v4.00で名称変更と新規要素追加
134// ============================================================================
135
136#[derive(Debug, Serialize, Deserialize)]
137pub struct Core400 {
138    // 岩石土区分 → 工学的地質区分名現場土質名
139    #[serde(rename = "工学的地質区分名現場土質名")]
140    pub engineering_geology_classifications: Vec<EngineeringGeologyClassification400>,
141    #[serde(default, rename = "色調")]
142    pub colors: Vec<Color210>, // v2.10を流用
143    #[serde(default, rename = "観察記事")]
144    pub observational_articles: Vec<ObservationalArticle210>, // v2.10を流用
145    #[serde(default, rename = "観察記事枠線")]
146    pub observational_article_frames: Vec<ObservationalArticleFrame210>, // v2.10を流用
147    #[serde(default, rename = "標準貫入試験")]
148    pub standard_penetration_tests: Vec<StandardPenetrationTest400>, // v4.00で単位変更
149    #[serde(default, rename = "標準貫入試験詳細データ")]
150    pub standard_penetration_test_details: Vec<StandardPenetrationTestDetail210>, // v2.10を流用
151    #[serde(default, rename = "ルジオン試験")]
152    pub lugeon_tests: Vec<LugeonTest210>, // v2.10を流用
153    #[serde(default, rename = "ルジオン試験詳細データ")]
154    pub lugeon_test_details: Vec<LugeonTestDetail210>, // v2.10を流用
155    #[serde(default, rename = "相対密度稠度")]
156    pub relative_density_consistency: Vec<RelativeDensityConsistency210>, // v2.10を流用
157    #[serde(default, rename = "硬軟区分判定表")]
158    pub hardness_classification_table: Vec<HardnessClassificationTable210>, // v2.10を流用
159    #[serde(default, rename = "硬軟区分")]
160    pub hardness_classifications: Vec<HardnessClassification300>, // v3.00を流用
161    // コア形状区分 → ボーリングコアの形状区分
162    #[serde(default, rename = "ボーリングコアの形状区分判定表")]
163    pub boring_core_shape_classification_table: Vec<CoreShapeClassificationTable210>, // v2.10を流用(名称のみ変更)
164    #[serde(default, rename = "ボーリングコアの形状区分")]
165    pub boring_core_shape_classifications: Vec<CoreShapeClassification300>, // v3.00を流用(名称のみ変更)
166    // 割れ目区分 → 割れ目の状態区分
167    #[serde(default, rename = "割れ目の状態区分判定表")]
168    pub crack_state_classification_table: Vec<FractureClassificationTable210>, // v2.10を流用(名称のみ変更)
169    #[serde(default, rename = "割れ目の状態区分")]
170    pub crack_state_classifications: Vec<FractureClassification300>, // v3.00を流用(名称のみ変更)
171    // 風化区分 → 風化の程度区分
172    #[serde(default, rename = "風化の程度区分判定表")]
173    pub weathering_degree_classification_table: Vec<WeatheringClassificationTable210>, // v2.10を流用(名称のみ変更)
174    #[serde(default, rename = "風化の程度区分")]
175    pub weathering_degree_classifications: Vec<WeatheringClassification300>, // v3.00を流用(名称のみ変更)
176    // 変質区分 → 熱水変質の程度区分
177    #[serde(default, rename = "熱水変質の程度区分判定表")]
178    pub hydrothermal_alteration_degree_classification_table: Vec<AlterationClassificationTable210>, // v2.10を流用(名称のみ変更)
179    #[serde(default, rename = "熱水変質の程度区分")]
180    pub hydrothermal_alteration_degree_classifications: Vec<AlterationClassification300>, // v3.00を流用(名称のみ変更)
181    // 破砕度(v4.00で新規追加)
182    #[serde(default, rename = "破砕度判定表")]
183    pub crushing_degree_classification_table: Vec<CrushingDegreeClassificationTable400>,
184    #[serde(default, rename = "破砕度")]
185    pub crushing_degrees: Vec<CrushingDegree400>,
186    // 孔内水平載荷試験 → 孔内載荷試験
187    #[serde(default, rename = "孔内載荷試験")]
188    pub borehole_loading_tests: Vec<BoreholeHorizontalLoadTest210>, // v2.10を流用(名称のみ変更)
189    #[serde(default, rename = "透水試験")]
190    pub permeability_tests: Vec<PermeabilityTest210>, // v2.10を流用
191    #[serde(default, rename = "P波試験")]
192    pub p_wave_tests: Vec<PWaveTest210>, // v2.10を流用
193    #[serde(default, rename = "S波試験")]
194    pub s_wave_tests: Vec<SWaveTest210>, // v2.10を流用
195    #[serde(default, rename = "その他原位置試験")]
196    pub other_in_situ_tests: Vec<OtherInSituTest210>, // v2.10を流用
197    #[serde(default, rename = "試料採取")]
198    pub sample_collections: Vec<SampleCollection210>, // v2.10を流用
199    #[serde(default, rename = "地盤材料の工学的分類")]
200    pub ground_material_classifications: Vec<GroundMaterialClassification210>, // v2.10を流用
201    #[serde(default, rename = "地質時代")]
202    pub geological_ages: Vec<GeologicalAge300>, // v3.00を流用
203    #[serde(default, rename = "地層岩体区分")]
204    pub stratum_rock_classifications: Vec<StratumRockClassification210>, // v2.10を流用
205    #[serde(default, rename = "孔内水位")]
206    pub borehole_water_levels: Vec<BoreholeWaterLevel400>, // v4.00で水位種別コード削除
207    // 掘削工程 → 削孔工程
208    #[serde(default, rename = "削孔工程")]
209    pub drilling_processes: Vec<DrillingProcess400>, // v4.00でフィールド名変更
210    #[serde(default, rename = "孔径孔壁保護")]
211    pub borehole_diameter_protections: Vec<BoreholeDiameterProtection210>, // v2.10を流用
212    // 掘進速度 → 削孔速度
213    #[serde(default, rename = "削孔速度")]
214    pub drilling_speeds: Vec<DrillingSpeed400>, // v4.00でフィールド名変更
215    #[serde(default, rename = "コアチューブビット")]
216    pub core_tube_bits: Vec<CoreTubeBit210>, // v2.10を流用
217    #[serde(default, rename = "給圧条件")]
218    pub pressure_conditions: Vec<PressureCondition210>, // v2.10を流用
219    #[serde(default, rename = "回転数")]
220    pub rotation_speeds: Vec<RotationSpeed210>, // v2.10を流用
221    #[serde(default, rename = "送水条件")]
222    pub water_supply_conditions: Vec<WaterSupplyCondition210>, // v2.10を流用
223    #[serde(default, rename = "断層破砕帯区分")]
224    pub fault_fracture_zone_classifications: Vec<FaultFractureZoneClassification210>, // v2.10を流用
225    #[serde(default, rename = "コア採取率")]
226    pub core_recovery_rates: Vec<CoreRecoveryRate300>, // v3.00を流用
227    #[serde(default, rename = "最大コア長")]
228    pub maximum_core_lengths: Vec<MaximumCoreLength300>, // v3.00を流用
229    #[serde(default, rename = "RQD")]
230    pub rqds: Vec<RQD210>, // v2.10を流用
231    // コア質量(v4.00で新規追加)
232    #[serde(default, rename = "コア質量")]
233    pub core_masses: Vec<CoreMass400>,
234    #[serde(default, rename = "岩級区分判定表")]
235    pub rock_class_classification_table: Vec<RockClassClassificationTable210>, // v2.10を流用
236    #[serde(default, rename = "岩級区分")]
237    pub rock_class_classifications: Vec<RockClassClassification300>, // v3.00を流用
238    #[serde(default, rename = "保孔管")]
239    pub casing_pipes: Vec<CasingPipe210>, // v2.10を流用
240    #[serde(default, rename = "計測機器")]
241    pub measuring_instruments: Vec<MeasuringInstrument210>, // v2.10を流用
242    // 地下水検層試験 → トレーサーによる地下水流動層検層
243    #[serde(default, rename = "トレーサーによる地下水流動層検層")]
244    pub tracer_groundwater_flow_layer_loggings: Vec<TracerGroundwaterFlowLayerLogging400>, // v4.00で名称変更
245    #[serde(default, rename = "トレーサーによる地下水流動層検層詳細データ")]
246    pub tracer_groundwater_flow_layer_logging_details:
247        Vec<TracerGroundwaterFlowLayerLoggingDetail400>, // v4.00で名称変更
248    #[serde(default, rename = "トレーサーによる地下水流動層検層判定結果")]
249    pub tracer_groundwater_flow_layer_logging_results:
250        Vec<TracerGroundwaterFlowLayerLoggingResult400>, // v4.00で名称変更
251    #[serde(default, rename = "備考")]
252    pub remarks: Vec<Remark210>, // v2.10を流用
253    #[serde(default, rename = "フリー情報")]
254    pub free_info: Vec<FreeInfo>,
255}
256
257// ============================================================================
258// 工学的地質区分名現場土質名 - v4.00で岩石土区分から名称変更
259// 構造はv3.00の岩石土区分と同じ
260// ============================================================================
261
262#[derive(Debug, Serialize, Deserialize)]
263pub struct EngineeringGeologyClassification400 {
264    #[serde(rename = "工学的地質区分名現場土質名_下端深度")]
265    pub depth: Option<String>,
266    #[serde(rename = "工学的地質区分名現場土質名_工学的地質区分名現場土質名")]
267    pub name: Option<String>,
268    #[serde(
269        default,
270        rename = "工学的地質区分名現場土質名_工学的地質区分名現場土質名記号"
271    )]
272    pub symbol: Option<String>,
273    #[serde(rename = "工学的地質区分名現場土質名_岩石群")]
274    pub rock_groups: Vec<RockGroup400>,
275}
276
277#[derive(Debug, Serialize, Deserialize)]
278pub struct RockGroup400 {
279    #[serde(rename = "工学的地質区分名現場土質名_岩石群コード")]
280    pub rock_group_code: Option<String>,
281    #[serde(rename = "工学的地質区分名現場土質名_岩石土コード")]
282    pub rock_soil_codes: Vec<RockSoilCode400>,
283}
284
285#[derive(Debug, Serialize, Deserialize)]
286pub struct RockSoilCode400 {
287    #[serde(default, rename = "工学的地質区分名現場土質名_岩相")]
288    pub lithofacies: Option<String>,
289    #[serde(default, rename = "工学的地質区分名現場土質名_岩石")]
290    pub rock: Option<String>,
291    #[serde(default, rename = "工学的地質区分名現場土質名_変成岩岩相")]
292    pub metamorphic_rock_lithofacies: Option<String>,
293    #[serde(default, rename = "工学的地質区分名現場土質名_変成岩岩石")]
294    pub metamorphic_rock: Option<String>,
295}
296
297// ============================================================================
298// 標準貫入試験 - v4.00で単位変更(cm → mm)
299// ============================================================================
300
301#[derive(Debug, Serialize, Deserialize)]
302pub struct StandardPenetrationTest400 {
303    #[serde(rename = "標準貫入試験_開始深度")]
304    pub start_depth: Option<String>,
305    // 単位変更: 0-10cm → 0-100mm
306    #[serde(default, rename = "標準貫入試験_0_100打撃回数")]
307    pub hit_count_0_100: Option<String>,
308    #[serde(default, rename = "標準貫入試験_0_100貫入量")]
309    pub penetration_0_100: Option<String>,
310    // 単位変更: 10-20cm → 100-200mm
311    #[serde(default, rename = "標準貫入試験_100_200打撃回数")]
312    pub hit_count_100_200: Option<String>,
313    #[serde(default, rename = "標準貫入試験_100_200貫入量")]
314    pub penetration_100_200: Option<String>,
315    // 単位変更: 20-30cm → 200-300mm
316    #[serde(default, rename = "標準貫入試験_200_300打撃回数")]
317    pub hit_count_200_300: Option<String>,
318    #[serde(default, rename = "標準貫入試験_200_300貫入量")]
319    pub penetration_200_300: Option<String>,
320    #[serde(rename = "標準貫入試験_合計打撃回数")]
321    pub total_hit_count: Option<String>,
322    #[serde(rename = "標準貫入試験_合計貫入量")]
323    pub total_penetration: Option<String>,
324    #[serde(default, rename = "標準貫入試験_備考")]
325    pub remarks: Option<String>,
326}
327
328// ============================================================================
329// 破砕度 - v4.00で新規追加
330// ============================================================================
331
332#[derive(Debug, Serialize, Deserialize)]
333pub struct CrushingDegreeClassificationTable400 {
334    #[serde(default, rename = "破砕度判定表_項目名")]
335    pub item_names: Vec<String>,
336    #[serde(default, rename = "破砕度判定表_判定")]
337    pub judgments: Vec<CrushingDegreeJudgment400>,
338}
339
340#[derive(Debug, Serialize, Deserialize)]
341pub struct CrushingDegreeJudgment400 {
342    #[serde(rename = "破砕度判定表_コード")]
343    pub code: Option<String>,
344    #[serde(rename = "破砕度判定表_記号")]
345    pub symbol: Option<String>,
346    #[serde(default, rename = "破砕度判定表_説明")]
347    pub descriptions: Vec<String>,
348}
349
350#[derive(Debug, Serialize, Deserialize)]
351pub struct CrushingDegree400 {
352    #[serde(rename = "破砕度_上端深度")]
353    pub start_depth: Option<String>,
354    #[serde(rename = "破砕度_下端深度")]
355    pub end_depth: Option<String>,
356    #[serde(default, rename = "破砕度_破砕度")]
357    pub crushing_degree: Option<String>,
358}
359
360// ============================================================================
361// コア質量 - v4.00で新規追加
362// ============================================================================
363
364#[derive(Debug, Serialize, Deserialize)]
365pub struct CoreMass400 {
366    #[serde(rename = "コア質量_下端深度")]
367    pub depth: Option<String>,
368    #[serde(default, rename = "コア質量_コア質量")]
369    pub core_mass: Option<String>,
370}
371
372// ============================================================================
373// 孔内水位 - v4.00で水位種別コード削除、掘削状況→削孔状況
374// ============================================================================
375
376#[derive(Debug, Serialize, Deserialize)]
377pub struct BoreholeWaterLevel400 {
378    #[serde(rename = "孔内水位_測定年月日")]
379    pub measurement_date: Option<String>,
380    #[serde(rename = "孔内水位_削孔状況コード")] // v3.00: 掘削状況コード
381    pub drilling_status_code: Option<String>,
382    #[serde(rename = "孔内水位_削孔状況")] // v3.00: 掘削状況
383    pub drilling_status: Option<String>,
384    #[serde(rename = "孔内水位_孔内水位")]
385    pub water_level: Option<String>,
386    // v4.00で削除: 孔内水位_水位種別コード
387    #[serde(default, rename = "孔内水位_水位種別備考")]
388    pub water_level_type_remarks: Option<String>,
389}
390
391// ============================================================================
392// 削孔工程 - v4.00で掘削工程から名称変更、掘進深度→削孔深度
393// ============================================================================
394
395#[derive(Debug, Serialize, Deserialize)]
396pub struct DrillingProcess400 {
397    #[serde(rename = "削孔工程_開始年月日")] // v3.00: 掘削工程_開始年月日
398    pub start_date: Option<String>,
399    #[serde(rename = "削孔工程_終了年月日")] // v3.00: 掘削工程_終了年月日
400    pub end_date: Option<String>,
401    #[serde(rename = "削孔工程_削孔深度")] // v3.00: 掘削工程_掘進深度
402    pub drilling_depth: Option<String>,
403    #[serde(default, rename = "削孔工程_作業内容")] // v3.00: 掘削工程_作業内容
404    pub work_content: Option<String>,
405}
406
407// ============================================================================
408// 削孔速度 - v4.00で掘進速度から名称変更
409// ============================================================================
410
411#[derive(Debug, Serialize, Deserialize)]
412pub struct DrillingSpeed400 {
413    #[serde(rename = "削孔速度_上端深度")] // v3.00: 掘進速度_上端深度
414    pub start_depth: Option<String>,
415    #[serde(rename = "削孔速度_下端深度")] // v3.00: 掘進速度_下端深度
416    pub end_depth: Option<String>,
417    #[serde(default, rename = "削孔速度_削孔速度")] // v3.00: 掘進速度_掘進速度
418    pub drilling_speed: Option<String>,
419}
420
421// ============================================================================
422// トレーサーによる地下水流動層検層 - v4.00で地下水検層試験から名称変更
423// 掘削深度→削孔深度
424// ============================================================================
425
426#[derive(Debug, Serialize, Deserialize)]
427pub struct TracerGroundwaterFlowLayerLogging400 {
428    #[serde(rename = "トレーサーによる地下水流動層検層_検層番号")]
429    // v3.00: 地下水検層試験_試験番号
430    pub test_number: Option<String>,
431    #[serde(rename = "トレーサーによる地下水流動層検層_上端深度")]
432    pub start_depth: Option<String>,
433    #[serde(rename = "トレーサーによる地下水流動層検層_下端深度")]
434    pub end_depth: Option<String>,
435    #[serde(rename = "トレーサーによる地下水流動層検層_削孔深度")] // v3.00: 掘削深度
436    pub drilling_depth: Option<String>,
437    #[serde(rename = "トレーサーによる地下水流動層検層_孔内水位")]
438    pub borehole_water_level: Option<String>,
439    #[serde(rename = "トレーサーによる地下水流動層検層_検層方法コード")] // v3.00: 試験方法コード
440    pub test_method_code: Option<String>,
441    #[serde(rename = "トレーサーによる地下水流動層検層_電解質溶液濃度")]
442    pub electrolyte_concentration: Option<String>,
443    #[serde(default, rename = "トレーサーによる地下水流動層検層_測定時間")]
444    pub measurement_times: Vec<String>,
445}
446
447#[derive(Debug, Serialize, Deserialize)]
448pub struct TracerGroundwaterFlowLayerLoggingDetail400 {
449    #[serde(rename = "トレーサーによる地下水流動層検層詳細データ_検層番号")] // v3.00: 試験番号
450    pub test_number: Option<String>,
451    #[serde(rename = "トレーサーによる地下水流動層検層詳細データ_測定深度")]
452    pub measurement_depth: Option<String>,
453    #[serde(
454        default,
455        rename = "トレーサーによる地下水流動層検層詳細データ_比抵抗値"
456    )]
457    pub resistivity_values: Vec<String>,
458}
459
460#[derive(Debug, Serialize, Deserialize)]
461pub struct TracerGroundwaterFlowLayerLoggingResult400 {
462    #[serde(rename = "トレーサーによる地下水流動層検層判定結果_上端深度")]
463    pub start_depth: Option<String>,
464    #[serde(rename = "トレーサーによる地下水流動層検層判定結果_下端深度")]
465    pub end_depth: Option<String>,
466    #[serde(rename = "トレーサーによる地下水流動層検層判定結果_地下水流動層検層結果")]
467    pub result: Option<String>,
468}
469
470// ============================================================================
471// ClassificationInfo trait implementation
472// ============================================================================
473
474impl ClassificationInfo for EngineeringGeologyClassification400 {
475    fn rock_groups(&self) -> Vec<RockGroupInfo> {
476        self.rock_groups
477            .iter()
478            .map(|g| {
479                let code = g
480                    .rock_group_code
481                    .as_deref()
482                    .and_then(RockGroupCode::from_code)
483                    .unwrap_or(RockGroupCode::Single);
484
485                let constituents = g
486                    .rock_soil_codes
487                    .iter()
488                    .map(|c| Constituent::Coded {
489                        lithofacies: c.lithofacies.clone(),
490                        rock: c.rock.clone(),
491                        metamorphic_rock_lithofacies: c.metamorphic_rock_lithofacies.clone(),
492                        metamorphic_rock: c.metamorphic_rock.clone(),
493                    })
494                    .collect();
495
496                RockGroupInfo { code, constituents }
497            })
498            .collect()
499    }
500}