-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmod.rs
More file actions
180 lines (173 loc) · 6.93 KB
/
Copy pathmod.rs
File metadata and controls
180 lines (173 loc) · 6.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//! Per-class element decoders.
//!
//! Each submodule implements [`crate::walker::ElementDecoder`] for
//! one Revit class. Adding a new class is a three-file change:
//!
//! 1. Add `mod my_class;` here.
//! 2. Register it in [`all_decoders`] so the walker dispatch table
//! picks it up.
//! 3. Implement `ElementDecoder` in `src/elements/my_class.rs` —
//! see `level.rs` as the reference example.
//!
//! See `docs/extending-layer-5b.md` for the contributor walkthrough.
//!
//! # Relationship to the generic decoder
//!
//! [`crate::walker::decode_instance`] is the generic fallback — it
//! walks any class's declared fields using the schema's
//! `FieldType` classifications. It always works, but the output is
//! untyped (each field shows up as an `InstanceField` variant).
//!
//! Concrete decoders in this module add a typed layer on top: they
//! call `decode_instance` first, then pattern-match the `fields`
//! vector into a class-specific struct (e.g. `Level { name,
//! elevation, is_building_story, … }`). Callers who want typed
//! Wall / Floor / Door values use these; callers who want a
//! uniform untyped dump use `decode_instance` directly.
pub mod annotations;
pub mod category;
pub mod ceiling;
pub mod circulation;
pub mod curtain_wall;
pub mod drafting;
pub mod family;
pub mod floor;
pub mod foundation_and_furnishings;
pub mod generic;
pub mod grid;
pub mod level;
pub mod mep;
pub mod openings;
pub mod parameters;
pub mod project_organization;
pub mod reference_planes;
pub mod reference_points;
pub mod roof;
pub mod structural;
pub mod styling;
pub mod wall;
pub mod zones;
use crate::walker::ElementDecoder;
/// Every registered [`ElementDecoder`] in insertion order.
///
/// The walker dispatch table is built from this list at runtime.
/// Future registration helpers (inventory crate, etc.) could replace
/// this with compile-time discovery; for now an explicit Vec keeps
/// it obvious what ships with the crate.
pub fn all_decoders() -> Vec<Box<dyn ElementDecoder>> {
vec![
Box::new(level::LevelDecoder),
Box::new(category::CategoryDecoder),
Box::new(category::SubcategoryDecoder),
Box::new(styling::MaterialDecoder),
Box::new(styling::FillPatternDecoder),
Box::new(styling::LinePatternDecoder),
Box::new(styling::LineStyleDecoder),
Box::new(reference_points::BasePointDecoder),
Box::new(reference_points::SurveyPointDecoder),
Box::new(reference_points::ProjectPositionDecoder),
Box::new(grid::GridDecoder),
Box::new(grid::GridTypeDecoder),
Box::new(reference_planes::ReferencePlaneDecoder),
Box::new(wall::WallDecoder),
Box::new(wall::WallTypeDecoder),
Box::new(floor::FloorDecoder),
Box::new(floor::FloorTypeDecoder),
Box::new(roof::RoofDecoder),
Box::new(roof::RoofTypeDecoder),
Box::new(ceiling::CeilingDecoder),
Box::new(ceiling::CeilingTypeDecoder),
Box::new(openings::DoorDecoder),
Box::new(openings::WindowDecoder),
Box::new(structural::ColumnDecoder),
Box::new(structural::StructuralColumnDecoder),
Box::new(structural::BeamDecoder),
Box::new(structural::StructuralFramingDecoder),
Box::new(circulation::StairDecoder),
Box::new(circulation::StairTypeDecoder),
Box::new(circulation::RailingDecoder),
Box::new(circulation::RailingTypeDecoder),
Box::new(zones::RoomDecoder),
Box::new(zones::AreaDecoder),
Box::new(zones::SpaceDecoder),
Box::new(foundation_and_furnishings::StructuralFoundationDecoder),
Box::new(foundation_and_furnishings::FurnitureDecoder),
Box::new(foundation_and_furnishings::FurnitureSystemDecoder),
Box::new(foundation_and_furnishings::CaseworkDecoder),
Box::new(foundation_and_furnishings::RebarDecoder),
Box::new(project_organization::PhaseDecoder),
Box::new(project_organization::DesignOptionDecoder),
Box::new(project_organization::WorksetDecoder),
Box::new(generic::GenericModelDecoder),
Box::new(generic::MassDecoder),
Box::new(curtain_wall::CurtainWallDecoder),
Box::new(curtain_wall::CurtainGridDecoder),
Box::new(curtain_wall::CurtainMullionDecoder),
Box::new(curtain_wall::CurtainPanelDecoder),
Box::new(family::SymbolDecoder),
Box::new(family::FamilyInstanceDecoder),
Box::new(drafting::ViewDecoder),
Box::new(drafting::SheetDecoder),
Box::new(drafting::ScheduleDecoder),
Box::new(drafting::ScheduleViewDecoder),
Box::new(annotations::DimensionDecoder),
Box::new(annotations::TagDecoder),
Box::new(annotations::TextNoteDecoder),
Box::new(annotations::AnnotationDecoder),
Box::new(project_organization::RevisionDecoder),
Box::new(parameters::ParameterElementDecoder),
Box::new(parameters::SharedParameterDecoder),
Box::new(mep::ElectricalEquipmentDecoder),
Box::new(mep::ElectricalFixtureDecoder),
Box::new(mep::LightingFixtureDecoder),
Box::new(mep::LightingDeviceDecoder),
Box::new(mep::DuctDecoder),
Box::new(mep::DuctFittingDecoder),
Box::new(mep::MechanicalEquipmentDecoder),
Box::new(mep::PipeDecoder),
Box::new(mep::PipeFittingDecoder),
Box::new(mep::PlumbingFixtureDecoder),
Box::new(mep::SpecialtyEquipmentDecoder),
// L5B-54: AProperty* value-carrier classes. The schema
// represents every element's parameter values as instances
// of one of these subclasses, keyed by name to a matching
// ParameterElement definition.
Box::new(parameters::APropertyDecoder),
Box::new(parameters::APropertyBooleanDecoder),
Box::new(parameters::APropertyIntegerDecoder),
Box::new(parameters::APropertyEnumDecoder),
Box::new(parameters::APropertyDouble1Decoder),
Box::new(parameters::APropertyDouble3Decoder),
Box::new(parameters::APropertyFloatDecoder),
Box::new(parameters::APropertyFloat3Decoder),
]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn all_decoders_includes_level() {
let decoders = all_decoders();
let names: Vec<&str> = decoders.iter().map(|d| d.class_name()).collect();
assert!(names.contains(&"Level"));
}
#[test]
fn all_decoders_includes_category_and_subcategory() {
let decoders = all_decoders();
let names: Vec<&str> = decoders.iter().map(|d| d.class_name()).collect();
assert!(names.contains(&"Category"));
assert!(names.contains(&"Subcategory"));
}
#[test]
fn decoder_class_names_are_unique() {
let decoders = all_decoders();
let mut seen = std::collections::BTreeSet::new();
for d in &decoders {
assert!(
seen.insert(d.class_name()),
"duplicate decoder for class {}",
d.class_name()
);
}
}
}