ruststep

repository·master·Indexed 41 days ago

https://github.com/ricosjp/ruststep

An experimental suite of pure Rust crates for handling STEP (Standard for the Exchange of Product model data) and the EXPRESS schema language (ISO 10303-11). It includes the espr compiler for generating Rust struct definitions from EXPRESS schemas and tools for STEP file serialization and deserialization.

Tokens
18.1K
Snippets
74
Records
95
Agent score
51%

What's inside ruststep

  1. Overview of the ruststep ecosystem

    master

    ruststep is a collection of pure Rust crates designed for working with STEP (Standard for the Exchange of Product model data). It aims to replace stepcode and provides tools to compile EXPRESS schemas and handle STEP file serialization/deserialization.

    Warning: This project is in an experimental stage. DO NOT USE FOR PRODUCT.

    The ecosystem consists of four main crates:

    • espr: An EXPRESS Language (ISO 10303-11) compiler.
    • espr-derive: A procedural macro crate used for running the espr compiler.
    • ruststep: Provides functionality to serialize and deserialize STEP files.
    • ruststep-derive: A procedural macro helper crate.
  2. Understand STEP and EXPRESS concepts

    master

    To use ruststep effectively, it is helpful to understand the relationship between STEP and EXPRESS, which can be compared to Protocol Buffers:

    ConceptProtocol BuffersSTEP (ISO 10303)
    Schema LanguageProtocol Buffers LanguageEXPRESS Language (ISO 10303-11)
    Schema file*.proto*.exp
    Data formatEncoded Binary"Exchange structure" / STEP file (*.step, *.stp, *.p21)
    Compilerprotocesprc

    Key Terms:

    • STEP File: The serialized data format (usually ASCII text via ISO-10303-21 or XML via ISO-10303-28).
    • EXPRESS: The schema language used to define the data structures.
    • Application Protocol (AP): A class of defined schemas (e.g., AP203 used in CAD).
  3. What is the STEP ecosystem?

    master

    STEP (Standard for the Exchange of Product model data) consists of three main components:

    • EXPRESS Schema: A schema language (standardized as ISO-10303-11) used to define the structure of data. Entities in EXPRESS are similar to structs in Rust.
    • Exchange Structure (STEP file): The data format (standardized as ISO-10303-21) where actual data is stored. It consists of sections like HEADER, DATA, and SIGNATURE.
    • Schemas: Specific implementations of EXPRESS, such as AP203 for CAD components.

    In a STEP file, the DATA section contains indexed instances (e.g., #1 = A(1.0, 2.0);). The HEADER section specifies which schema (e.g., FILE_SCHEMA(('my_first_schema'))) the data must adhere to. espr helps create programs that validate these exchange structures against their corresponding schemas.

  4. Use STEP-aware parser combinators

    master

    The ruststep::parser::combinator module provides extended nom parser combinators specifically designed to handle the STEP exchange structure. These combinators automatically handle token separators common in STEP files, such as whitespace and comments (/* ... */).

    Key features include:

    • Automatic Comment Handling: Combinators like ignorable, many0_, and many1_ can skip over comments and whitespace between tokens.
    • Exchange-Specific Separators: Specialized functions for handling whitespace and comments as separators in sequences.
    • Custom Parser Trait: The ExchangeParser trait extends nom::Parser to work with VerboseError for better error reporting in STEP parsing tasks.
  5. Identify Entity Instance types

    master

    In the DATA section of a STEP file, each line is an EntityInstance. An instance can be one of two types:

    1. Simple: A single Record associated with an ID (e.g., #1 = A(1, 2);).
    2. Complex: A SubSuperRecord associated with an ID, used for external mapping of complex entities (e.g., #5 = (PERSON('Name') EMPLOYEE(10));).
  6. The structure of a STEP file

    master

    A STEP file (ASCII encoding of an exchange structure) consists of the following sections:

    • HEADER (Required)
    • ANCHOR (Optional)
    • REFERENCE (Optional)
    • DATA (Required)
    • SIGNATURE (Optional)

    The tokenization process can be performed without an EXPRESS schema, as the syntax is common across schemas. The specific schema is identified within the HEADER section and is used to interpret the resulting AST.

  7. Understand Inverse Relationships with InverseAttribute

    master

    The InverseAttribute struct represents an INVERSE clause in EXPRESS, which defines a relationship back to a parent entity.

    Example logic: If ENTITY door has attribute handle : knob;, then ENTITY knob can have an INVERSE relationship opens : door FOR handle;.

    Fields:

    • name: The name of the inverse relationship (e.g., opens).
    • dest: The name of the destination entity (e.g., door).
    • dest_aggregation: The aggregation type for the destination (e.g., Set, Bag, or None).
    • attribute: The name of the attribute in the parent entity being referenced (e.g., handle).
    • attribute_prefix: An optional prefix if the attribute is a sub-attribute of the destination entity.
    pub struct InverseAttribute {
        pub name: AttributeDecl,
        pub dest: String,
        pub dest_aggregation: AggregationOption,
        pub attribute: String,
        pub attribute_prefix: Option<String>,
    }
  8. Understand the espr compiler pipeline

    master

    The espr crate implements a compiler for the EXPRESS language. The compilation process follows these stages:

    1. Tokenize: Reads EXPRESS input and parses it into an Abstract Syntax Tree (AST) using the ast and parser modules.
    2. Legalize: Converts the AST into an Intermediate Representation (IR) using the ir module. This stage implements the ir::Legalize trait to prepare the data for code generation.
    3. Code Generation: The codegen::rust module generates Rust code from the IR. This generated code includes procedural macros that eventually call ruststep to produce the final Rust code.
  9. Understand the STEP (ISO-10303-21) file structure

    master

    The ruststep crate is designed to read and write ASCII encoded exchange structures (STEP files) as defined by ISO-10303-21.

    A standard STEP file consists of:

    1. Start Marker: ISO-10303-21;
    2. HEADER Section: Contains metadata including FILE_DESCRIPTION, FILE_NAME, and FILE_SCHEMA.
    3. DATA Section: Contains the actual model data in the form of "Records".
      • A Record follows the pattern TYPE_NAME(parameter1, parameter2, ...).
      • Each record is identified by a unique number (e.g., #1 = ...).
      • Parameters can be floating numbers, strings, lists, enum values (like .T. or .F.), or references to other records (e.g., #1).
    4. End Marker: END-ISO-10303-21;
    ISO-10303-21;
    
    HEADER;
      FILE_DESCRIPTION(('...'), '3;1');
      FILE_NAME('...', '...', ('...', '...'), ('...', '...'), '...', '...', '...');
      FILE_SCHEMA(('...'));
    ENDSEC;
    
    DATA;
      #1 = CPT(0.0, 0.0, 0.0);
      #11 = VX(#1);
    ENDSEC;
    
    END-ISO-10303-21;
  10. Understand the Namespace IR structure

    master

    The Namespace struct serves as the central registry for an EXPRESS schema's intermediate representation. It consists of two primary components:

    1. names: A HashMap mapping a Scope to a list of available identifiers. Each identifier is stored as a tuple of (ScopeType, String, usize), where the usize is the index into the ast vector.
    2. ast: A vector of (Path, Named<'st>) tuples, providing an indexed collection of the actual AST nodes (Types or Entities) associated with their unique paths.

    You can access these via indexing:

    • namespace[scope] returns the list of names available in that scope.
    • namespace[index] returns the (Path, Named) pair at that index.
  11. Install ruststep with AP201 and AP203 support

    master

    By default, ruststep does not include the generated code for specific ISO schemas to keep compilation times fast. To use the application protocols for AP201 (Explicit draughting) or AP203 (Configuration controlled 3D design), you must explicitly enable them via Cargo features.

    Add the following to your Cargo.toml:

    [dependencies]
    ruststep = { version = "*", features = ["ap201", "ap203"] }
  12. Current capabilities of ruststep (v0.1.0)

    master

    As of version 0.1.0, the following features are available:

    • EXPRESS Compilation: A minimal compiler to generate Rust struct definitions from EXPRESS schemas.
    • Deserialization: Ability to deserialize ASCII STEP files into Rust structs.