Skip to content

Rust API Reference

Complete API documentation for the Rust crates.

Note: Full API documentation with source links is available via cargo doc --open

ifc-lite-core

Core parsing functionality.

Modules

pub mod parser;      // STEP tokenization
pub mod generated;   // IFC type definitions (IfcType)
pub mod decoder;     // Entity decoding
pub mod streaming;   // Streaming parser
pub mod schema_gen;  // Generated schema
pub mod error;       // Error types

Parser Module

Token

/// STEP token types
#[derive(Debug, Clone, PartialEq)]
pub enum Token<'a> {
    /// Entity reference (#123)
    EntityRef(u32),
    /// Keyword (IFCWALL)
    Keyword(&'a [u8]),
    /// String literal ('text')
    String(&'a [u8]),
    /// Integer value
    Integer(i64),
    /// Floating point value
    Float(f64),
    /// Enumeration (.ENUM.)
    Enum(&'a [u8]),
    /// Binary data ("0A1B2C")
    Binary(&'a [u8]),
    /// Undefined value (*)
    Asterisk,
    /// Null/omitted ($)
    Dollar,
    /// Punctuation
    OpenParen,
    CloseParen,
    Comma,
    Semicolon,
    Equals,
}

EntityScanner

/// Scans IFC file for entity locations
pub struct EntityScanner<'a> {
    // ...
}

impl<'a> EntityScanner<'a> {
    /// Create a scanner over the file bytes
    pub fn new<T>(content: &'a T) -> Self;

    /// Advance to the next entity: (express_id, type_name, start, end)
    pub fn next_entity(&mut self) -> Option<(u32, &'a str, usize, usize)>;
}

parse_entity

/// Parse a single entity definition into (express_id, type, attribute tokens)
pub fn parse_entity<'a, T>(input: &'a T) -> Result<(u32, IfcType, Vec<Token<'a>>)>;

Schema Module

IfcType

/// IFC entity type enumeration
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u16)]
pub enum IfcType {
    Unknown = 0,
    IfcProject = 1,
    IfcSite = 2,
    IfcBuilding = 3,
    IfcBuildingStorey = 4,
    IfcSpace = 5,
    IfcWall = 6,
    IfcWallStandardCase = 7,
    IfcDoor = 8,
    IfcWindow = 9,
    // ... ~50 common types
}

impl IfcType {
    /// Parse from type name
    pub fn from_name(name: &[u8]) -> Self;

    /// Get type name
    pub fn name(&self) -> &'static str;

    /// Check if type has geometry
    pub fn has_geometry(&self) -> bool;
}

has_geometry_by_name

/// Check if entity type typically has geometry
pub fn has_geometry_by_name(type_name: &str) -> bool;

Decoder Module

EntityDecoder

/// Decodes entity attributes from raw bytes
pub struct EntityDecoder<'a> {
    input: &'a [u8],
    index: &'a EntityIndex,
}

impl<'a> EntityDecoder<'a> {
    /// Create decoder with input buffer and index
    pub fn new(input: &'a [u8], index: &'a EntityIndex) -> Self;

    /// Decode entity by express ID
    pub fn decode(&self, express_id: u32) -> Result<DecodedEntity>;

    /// Decode entity attributes only
    pub fn decode_attributes(&self, express_id: u32) -> Result<Vec<AttributeValue>>;
}

EntityIndex

/// Index of entity locations in file
pub struct EntityIndex {
    locations: HashMap<u32, EntityLocation>,
    ordered_ids: Vec<u32>,
}

impl EntityIndex {
    /// Get entity count
    pub fn len(&self) -> usize;

    /// Get entity location
    pub fn get(&self, express_id: u32) -> Option<&EntityLocation>;

    /// Iterate over entities
    pub fn iter(&self) -> impl Iterator<Item = (u32, &EntityLocation)>;
}

EntityLocation

/// Location of entity in file
#[derive(Debug, Clone)]
pub struct EntityLocation {
    pub express_id: u32,
    pub offset: usize,
    pub length: usize,
    pub ifc_type: IfcType,
}

Streaming Module

ParseEvent

/// Events emitted during streaming parse
#[derive(Debug)]
pub enum ParseEvent {
    /// Parsing started
    Started { file_size: usize, timestamp: f64 },
    /// Entity discovered during scanning
    EntityScanned { id: u32, ifc_type: IfcType, position: usize },
    /// Geometry processing completed for an entity
    GeometryReady { id: u32, vertex_count: usize, triangle_count: usize },
    /// Progress update
    Progress {
        phase: String,
        percent: f32,
        entities_processed: usize,
        total_entities: usize,
    },
    /// Parsing completed
    Completed { duration_ms: f64, entity_count: usize, triangle_count: usize },
    /// Error (non-fatal)
    Error { message: String, position: Option<usize> },
}

StreamConfig

/// Configuration for streaming parser
#[derive(Debug, Clone)]
pub struct StreamConfig {
    /// Chunk size in bytes
    pub chunk_size: usize,
    /// Report progress every N entities
    pub progress_interval: usize,
    /// Continue on non-fatal errors
    pub ignore_errors: bool,
}

impl Default for StreamConfig {
    fn default() -> Self {
        Self {
            chunk_size: 1024 * 1024, // 1 MB
            progress_interval: 100,
            ignore_errors: true,
        }
    }
}

parse_stream

/// Stream parse an IFC file
pub fn parse_stream<'a>(
    input: &'a [u8],
    config: StreamConfig,
) -> impl Iterator<Item = ParseEvent> + 'a;

Schema Gen Module

AttributeValue

/// Decoded attribute value
#[derive(Debug, Clone)]
pub enum AttributeValue {
    Null,
    Integer(i64),
    Float(f64),
    String(String),
    Boolean(bool),
    Enum(String),
    EntityRef(u32),
    List(Vec<AttributeValue>),
    Derived,
}

impl AttributeValue {
    /// Get as integer
    pub fn as_int(&self) -> Option<i64>;

    /// Get as float
    pub fn as_float(&self) -> Option<f64>;

    /// Get as string
    pub fn as_str(&self) -> Option<&str>;

    /// Get as entity reference
    pub fn as_ref(&self) -> Option<u32>;

    /// Get as list
    pub fn as_list(&self) -> Option<&[AttributeValue]>;
}

DecodedEntity

/// Fully decoded entity
#[derive(Debug)]
pub struct DecodedEntity {
    pub express_id: u32,
    pub type_name: String,
    pub ifc_type: IfcType,
    pub attributes: Vec<AttributeValue>,
}

Error Module

/// Parser error type
#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Token error at position {position}: {message}")]
    Token { position: usize, message: String },

    #[error("Entity not found: #{0}")]
    EntityNotFound(u32),

    #[error("Invalid attribute at index {index}: {message}")]
    Attribute { index: usize, message: String },

    #[error("Unsupported schema: {0}")]
    UnsupportedSchema(String),

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
}

pub type Result<T> = std::result::Result<T, Error>;

ifc-lite-geometry

Geometry processing functionality.

Modules

pub mod mesh;           // Mesh data structures
pub mod triangulation;  // Polygon triangulation
pub mod profile;        // Profile handling
pub mod extrusion;      // Extrusion processing
pub mod csg;            // Boolean operations
pub mod router;         // Geometry routing
pub mod processors;     // Entity processors

Mesh Module

Mesh

/// Triangle mesh representation
#[derive(Debug, Clone)]
pub struct Mesh {
    pub express_id: u32,
    pub positions: Vec<f32>,
    pub normals: Vec<f32>,
    pub indices: Vec<u32>,
    pub color: [f32; 4],
}

impl Mesh {
    /// Create empty mesh
    pub fn new(express_id: u32) -> Self;

    /// Get vertex count
    pub fn vertex_count(&self) -> usize;

    /// Get triangle count
    pub fn triangle_count(&self) -> usize;

    /// Compute bounding box
    pub fn bounds(&self) -> BoundingBox;

    /// Apply transformation matrix
    pub fn transform(&mut self, matrix: &Matrix4<f64>);
}

BoundingBox

/// Axis-aligned bounding box
#[derive(Debug, Clone, Copy)]
pub struct BoundingBox {
    pub min: Point3<f64>,
    pub max: Point3<f64>,
}

impl BoundingBox {
    /// Create from points
    pub fn from_points(points: &[Point3<f64>]) -> Self;

    /// Get center point
    pub fn center(&self) -> Point3<f64>;

    /// Get size
    pub fn size(&self) -> Vector3<f64>;

    /// Merge with another box
    pub fn merge(&mut self, other: &BoundingBox);
}

Triangulation Module

/// Triangulate a 2D polygon with holes
pub fn triangulate_polygon(
    outer: &[Point2<f64>],
    holes: &[Vec<Point2<f64>>],
) -> Result<Vec<u32>>;

/// Triangulate a simple polygon (no holes)
pub fn triangulate_simple(
    points: &[Point2<f64>],
) -> Result<Vec<u32>>;

Profile Module

/// Extract profile points from IFC profile definition
pub fn extract_profile(
    decoder: &EntityDecoder,
    profile_id: u32,
) -> Result<ProfileData>;

/// Profile data with outer boundary and holes
#[derive(Debug)]
pub struct ProfileData {
    pub outer: Vec<Point2<f64>>,
    pub holes: Vec<Vec<Point2<f64>>>,
}

Extrusion Module

/// Process extruded area solid
pub fn process_extrusion(
    profile: &ProfileData,
    direction: Vector3<f64>,
    depth: f64,
) -> Result<Mesh>;

/// Extrusion parameters
#[derive(Debug)]
pub struct ExtrusionParams {
    pub direction: Vector3<f64>,
    pub depth: f64,
    pub position: Matrix4<f64>,
}

Router Module

/// Route geometry processing based on type
pub struct GeometryRouter {
    processors: HashMap<IfcType, Box<dyn GeometryProcessor>>,
}

impl GeometryRouter {
    /// Create router with default processors
    pub fn new() -> Self;

    /// Register custom processor
    pub fn register(&mut self, processor: Box<dyn GeometryProcessor>);

    /// Process entity geometry
    pub fn process(
        &self,
        decoder: &EntityDecoder,
        entity: &DecodedEntity,
    ) -> Result<Option<Mesh>>;
}

Processor Trait

/// Trait for geometry processors
pub trait GeometryProcessor: Send + Sync {
    /// Check if processor can handle entity
    fn can_process(&self, entity: &DecodedEntity) -> bool;

    /// Process entity into mesh
    fn process(
        &self,
        decoder: &EntityDecoder,
        entity: &DecodedEntity,
    ) -> Result<Mesh>;
}

ifc-lite-wasm

WebAssembly bindings.

IfcAPI

The WASM surface is split across rust/wasm-bindings/src/api/*.rs; every method is exported to JS under a camelCase js_name that mirrors pkg/ifc-lite.d.ts. The methods below are representative, not exhaustive.

/// Main IFC-Lite API
#[wasm_bindgen]
pub struct IfcAPI {
    // ...
}

#[wasm_bindgen]
impl IfcAPI {
    /// Create and initialize the IFC API
    #[wasm_bindgen(constructor)]
    pub fn new() -> Self;

    /// Fast SIMD entity scan; returns entity references for the data model
    #[wasm_bindgen(js_name = scanEntitiesFast)]
    pub fn scan_entities_fast(&self, content: &str) -> JsValue;

    /// Streaming geometry pre-pass; emits progress via `on_event`
    #[wasm_bindgen(js_name = buildPrePassStreaming)]
    pub fn build_pre_pass_streaming(
        &self,
        data: &[u8],
        on_event: &js_sys::Function,
        chunk_size: u32,
        disabled_type_names: Option<Vec<String>>,
        skip_type_geometry: bool,
    ) -> Result<JsValue, JsValue>;

    /// Mesh one batch of geometry jobs into a MeshCollection
    #[wasm_bindgen(js_name = processGeometryBatch)]
    pub fn process_geometry_batch(
        &self,
        data: &[u8],
        jobs_flat: &[u32],
        unit_scale: f64,
        // ... RTC offset, void keys, styles, material colours
    ) -> MeshCollection;

    /// Extract 2D profiles (outer boundary + holes) for parametric geometry
    #[wasm_bindgen(js_name = extractProfiles)]
    pub fn extract_profiles(&self, content: String, model_index: u32) -> ProfileCollection;

    /// Export glTF binary (GLB) from the model
    #[wasm_bindgen(js_name = exportGlb)]
    pub fn export_glb(
        &self,
        content: &[u8],
        include_metadata: bool,
        hidden: &[u32],
        isolated: &[u32],
        hidden_types_csv: String,
        lit: Option<bool>,
    ) -> Result<Vec<u8>, JsValue>;

    /// Export CSV (entities / properties / quantities / spatial)
    #[wasm_bindgen(js_name = exportCsv)]
    pub fn export_csv(
        &self,
        content: &[u8],
        mode: String,
        delimiter: String,
        include_properties: bool,
    ) -> Vec<u8>;
}

Building Documentation

Generate full Rustdoc documentation:

cd rust
cargo doc --no-deps --document-private-items --open

This will generate detailed documentation including:

  • All public and private items
  • Source code links
  • Examples from doc comments
  • Cross-references between items