High-performance IFC/STEP parser for building data, built on comp-cat-rs.
ifc-lite-core provides the core parsing functionality for
IFC (Industry Foundation Classes) files used in Building Information
Modeling (BIM). All effectful operations are expressed through the
comp-cat-rs effect system (Io, Stream), keeping the core
parsing logic pure and composable.
Capabilities:
- STEP Tokenization -- zero-copy parsing via
nom - Entity Scanning -- SIMD-accelerated entity discovery via
memchr, exposed as acomp_cat_rs::effect::stream::Stream - Lazy Decoding -- on-demand attribute parsing wrapped in
comp_cat_rs::effect::io::Io - Streaming Parser -- event-based parsing for large files with type filtering
use ifc_lite_core::{parse_entity, EntityId, IfcType, Error};
fn main() -> Result<(), Error> {
let input = "#123=IFCWALL('guid',$,$,$,'Wall-001',$,$,$);";
let (id, ifc_type, attrs) = parse_entity(input)?;
assert_eq!(id, EntityId::new(123));
assert_eq!(ifc_type, IfcType::IfcWall);
Ok(())
}use ifc_lite_core::{scan::scan_entities, Error};
fn main() -> Result<(), Error> {
let content = std::fs::read_to_string("model.ifc")?;
let entities = scan_entities(content)
.collect()
.run()?;
println!("Found {} entities", entities.len());
Ok(())
}use ifc_lite_core::{decode::{decode_entity, decode_by_id}, scan::build_entity_index, Error};
fn main() -> Result<(), Error> {
let content = std::fs::read_to_string("model.ifc")?;
let index = build_entity_index(&content);
// Decode a specific entity by id -- returns Io<Error, DecodedEntity>
let wall = decode_by_id(&content, &index, 42.into())
.run()?;
println!("Entity: {} ({})", wall.id(), wall.ifc_type());
Ok(())
}use ifc_lite_core::{streaming::{parse_stream, StreamConfig, ParseEvent}, Error};
fn main() -> Result<(), Error> {
let content = std::fs::read_to_string("model.ifc")?;
let events = parse_stream(content, StreamConfig::default())
.collect()
.run()?;
events.iter().for_each(|event| match event {
ParseEvent::EntityScanned { entity } => {
println!("#{}: {}", entity.id(), entity.ifc_type());
}
ParseEvent::Completed { entity_count } => {
println!("Done: {entity_count} entities");
}
_ => {}
});
Ok(())
}| Module | Purpose |
|---|---|
parse |
nom-based STEP tokenizer; pure &str -> Result API |
scan |
Entity scanning; returns Stream<Error, ScannedEntity> |
decode |
Entity decoding; returns Io<Error, DecodedEntity> |
streaming |
High-level parse events; returns Stream<Error, ParseEvent> |
schema |
Geometry and profile category lookups |
token |
Zero-copy Token<'a> sum type |
attribute |
Owned AttributeValue and DecodedEntity |
ifc_type |
IfcType enum covering IFC4X3 entity types |
entity_id |
EntityId newtype |
error |
Hand-rolled Error enum |
- Functional: no
mut, no loops, combinators everywhere - Type-driven: newtypes for domain primitives (
EntityId,IfcType) - Effect-aware: side effects wrapped in
comp-cat-rsIoandStream - Delay
run: stay inside effects via combinators; callrunonly at the boundary - Zero-copy tokenization:
Token<'a>borrows from input; ownedAttributeValuefor storage
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.