### Install cargo-insta CLI Source: https://github.com/ricosjp/ruststep/blob/master/espr/tests/README.md Install the `cargo-insta` command-line tool to manage snapshot testing workflows, including reviewing and accepting generated snapshots. ```bash cargo install cargo-insta ``` -------------------------------- ### ISO-10303-21 Header Example Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt This snippet shows the header section of an ISO-10303-21 file, defining file description, name, and schema. ```step ISO-10303-21; HEADER; FILE_DESCRIPTION(('Example physical file'), '2;1'); FILE_NAME('example.spf', '2001-01-29', ('IEC SC3D WG2'), (), 'Version 1', '', ''); FILE_SCHEMA(('example_schema')); ENDSEC; ``` -------------------------------- ### Bash: EXPRESS Compiler (esprc) Usage Source: https://context7.com/ricosjp/ruststep/llms.txt Provides command-line examples for using the `esprc` binary to compile EXPRESS schema files to Rust code. Includes checking schema syntax, generating Rust code, and controlling error output verbosity. ```bash # Check if EXPRESS file parses correctly esprc --check schema.exp ``` ```bash # Generate Rust code from EXPRESS schema esprc schema.exp > generated.rs ``` ```bash # Control error output verbosity esprc --num-error-lines 20 schema.exp ``` -------------------------------- ### Enable AP201 and AP203 Features in Cargo.toml Source: https://context7.com/ricosjp/ruststep/llms.txt To use pre-generated Application Protocols, specify the desired APs as features in your Cargo.toml file. This example enables support for AP201 and AP203. ```toml # Cargo.toml [dependencies] ruststep = { version = "0.4", features = ["ap201", "ap203"] } ``` -------------------------------- ### Resolve Entity References with EntityTable Source: https://context7.com/ricosjp/ruststep/llms.txt Demonstrates using `EntityTable` and `PlaceHolder` to handle entity references in STEP data, allowing for deferred resolution. This example shows parsing data with references and retrieving owned entities with resolved references. ```rust use ruststep::{ast::*, tables::*}; use std::str::FromStr; espr_derive::inline_express!(r#" SCHEMA test_schema; ENTITY a; x: REAL; y: REAL; END_ENTITY; ENTITY b; z: REAL; a: a; END_ENTITY; END_SCHEMA; "#); use test_schema::*; // Parse data section with references let data = r#" DATA; #1 = A(1.0, 2.0); #2 = A(3.0, 4.0); #3 = B(5.0, #1); #4 = B(6.0, A((7.0, 8.0))); ENDSEC; "#; // Create tables from data section let tables = Tables::from_str(data).unwrap(); // Get owned entity with resolved references let a1: A = EntityTable::::get_owned(&tables, 1).unwrap(); assert_eq!(a1, A { x: 1.0, y: 2.0 }); // B contains reference to A which gets resolved let b3: B = EntityTable::::get_owned(&tables, 3).unwrap(); assert_eq!(b3, B { z: 5.0, a: A { x: 1.0, y: 2.0 } }); // Inline A values are also supported let b4: B = EntityTable::::get_owned(&tables, 4).unwrap(); assert_eq!(b4, B { z: 6.0, a: A { x: 7.0, y: 8.0 } }); ``` -------------------------------- ### Rust: SubType/SuperType Inheritance Source: https://context7.com/ricosjp/ruststep/llms.txt Demonstrates how Ruststep supports EXPRESS entity inheritance with SUBTYPE/SUPERTYPE relationships, generating appropriate Rust enum types. Includes examples of accessing base and nested subtypes, and using generated 'Any' enum types for polymorphic access. ```rust use ruststep::{ast::*, tables::*}; use std::str::FromStr; espr_derive::inline_express!(r#" SCHEMA inheritance_schema; ENTITY base SUPERTYPE OF (ONEOF (sub)); x: REAL; END_ENTITY; ENTITY sub SUBTYPE OF (base); y: REAL; END_ENTITY; ENTITY subsub SUBTYPE OF (sub); z: REAL; END_ENTITY; END_SCHEMA; "#); use inheritance_schema::*; let data = r#" DATA; #1 = BASE(1.0); #2 = SUB(BASE((2.0)), 3.0); #3 = SUBSUB(#2, 4.0); ENDSEC; "#; let tables = Tables::from_str(data).unwrap(); // Get base entity let base: Base = EntityTable::::get_owned(&tables, 1).unwrap(); assert_eq!(base, Base { x: 1.0 }); // Get subtype with inherited fields let sub: Sub = EntityTable::::get_owned(&tables, 2).unwrap(); assert_eq!(sub, Sub { base: Base { x: 2.0 }, y: 3.0 }); // Get deeply nested subtype let subsub: Subsub = EntityTable::::get_owned(&tables, 3).unwrap(); assert_eq!(subsub.sub.base.x, 2.0); assert_eq!(subsub.z, 4.0); // Use generated "Any" enum types for polymorphic access let any: BaseAny = EntityTable::::get_owned(&tables, 2).unwrap(); match any { BaseAny::Base(b) => println!("Base: {:?}", b), BaseAny::Sub(s) => println!("Sub: {:?}", s), } ``` -------------------------------- ### Parsing STEP Files Source: https://context7.com/ricosjp/ruststep/llms.txt Demonstrates how to parse an entire STEP file into an Abstract Syntax Tree (AST) representation using the `ruststep::parser::parse` function. ```APIDOC ## Parsing STEP Files ### Description The `ruststep::parser::parse` function parses entire STEP files (exchange structures) into an AST representation containing header, data sections, anchors, and references. ### Method `ruststep::parser::parse` ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use std::{fs, path::PathBuf}; use ruststep::parser; // Parse a STEP file from disk let step_file = PathBuf::from("model.step"); let step_str = fs::read_to_string(step_file).unwrap(); // Parse the entire exchange structure let exchange = parser::parse(&step_str).unwrap(); // Access the parsed sections println!("Header records: {:?}", exchange.header); println!("Data sections: {}", exchange.data.len()); // Each data section contains entity instances for data_section in &exchange.data { for entity in &data_section.entities { println!("{:?}", entity); } } ``` ### Response #### Success Response (200) - **exchange** (struct) - An `Exchange` struct containing header and data sections. #### Response Example ```json { "header": { ... }, "data": [ { "entities": [ ... ] }, ... ] } ``` ``` -------------------------------- ### Update Attribute Redefinitions in ENTITY class_document_relationship Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt Corrects the redefinition of the 'related_tokens' attribute in 'class_document_relationship' to use a range starting from 1. ```text SELF\class_bsu_relationship.related_tokens : SET[0:?] OF document_bsu; SELF\class_bsu_relationship.related_tokens : SET[1:?] OF document_bsu; ``` -------------------------------- ### Review Snapshots with cargo-insta Source: https://github.com/ricosjp/ruststep/blob/master/espr/tests/README.md Run this command to initiate the snapshot review process. It will prompt you to accept or reject generated snapshots, allowing you to update or verify test outputs. ```bash cargo insta review ``` -------------------------------- ### Working with AST Records Source: https://context7.com/ricosjp/ruststep/llms.txt Explains how to work with `Record` structs, which represent typed data in STEP format, including parsing from strings and deserializing into Rust structs using serde. ```APIDOC ## Working with AST Records ### Description The `Record` struct represents typed data in STEP format. It can be parsed from strings and deserialized into Rust structs using serde. ### Method `ruststep::ast::Record::from_str`, `serde::Deserialize` ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use ruststep::ast::{Record, Parameter}; use serde::Deserialize; use std::str::FromStr; // Parse a simple record let record = Record::from_str("POINT(1.0, 2.0, 3.0)").unwrap(); assert_eq!(record.name, "POINT"); // Deserialize record into a custom struct #[derive(Debug, Clone, PartialEq, Deserialize)] #[serde(rename = "POINT")] struct Point { x: f64, y: f64, z: f64, } let point: Point = Point::deserialize(&record).unwrap(); assert_eq!(point, Point { x: 1.0, y: 2.0, z: 3.0 }); // Records can also be deserialized as HashMaps use std::collections::HashMap; let record = Record::from_str("DATA_ITEM(10, 20)").unwrap(); let map: HashMap> = HashMap::deserialize(&record).unwrap(); assert_eq!(map.get("DATA_ITEM"), Some(&vec![10, 20])); ``` ### Response #### Success Response (200) - **Record** (struct) - Represents a parsed STEP record. - **Point** (struct) - Example of a deserialized struct from a STEP record. - **HashMap** (struct) - Example of deserializing a record into a HashMap. #### Response Example ```json { "record": { "name": "POINT", "parameters": [ { "type": "Number", "value": 1.0 }, { "type": "Number", "value": 2.0 }, { "type": "Number", "value": 3.0 } ] }, "point": { "x": 1.0, "y": 2.0, "z": 3.0 }, "map": { "DATA_ITEM": [10, 20] } } ``` ``` -------------------------------- ### Rust: Error Handling in Ruststep Source: https://context7.com/ricosjp/ruststep/llms.txt Illustrates Ruststep's detailed error types for tokenization, deserialization, and entity lookup failures. Shows how to use the `Result` type and handle specific `Error` variants during STEP file parsing. ```rust use ruststep::error::{Error, Result}; use ruststep::parser; fn parse_step_file(content: &str) -> Result<()> { let exchange = parser::parse(content)?; // Process the exchange structure for data_section in &exchange.data { println!("Found {} entities", data_section.entities.len()); } Ok(()) } // Handle specific errors fn handle_errors() { let bad_input = "INVALID STEP DATA"; match parser::parse(bad_input) { Ok(_) => println!("Parsed successfully"), Err(Error::TokenizeFailed(e)) => { eprintln!("Tokenization error: {}", e); } Err(Error::UnknownEntity(id)) => { eprintln!("Unknown entity reference: #{}", id); } Err(Error::DuplicatedEntity(id)) => { eprintln!("Duplicate entity ID: #{}", id); } Err(e) => eprintln!("Other error: {}", e), } } ``` -------------------------------- ### Rust Test Template with Insta Source: https://github.com/ricosjp/ruststep/blob/master/espr/tests/README.md Use this template to create new snapshot tests. Replace `{{ Add EXPRESS schema you want to test }}` with your schema and `{{ test name }}` with a descriptive test name. Ensure `espr` and `insta` crates are available. ```rust use espr::{ast::SyntaxTree, codegen::rust::*, ir::IR}; const EXPRESS: &str = r#" {{ Add EXPRESS schema you want to test }} "#; #[test] fn {{ test name }}() { let st = SyntaxTree::parse(EXPRESS).unwrap(); let ir = IR::from_syntax_tree(&st).unwrap(); let tt = ir.to_token_stream(CratePrefix::External).to_string(); let tt = rustfmt(tt); insta::assert_snapshot!(tt, @""); } ``` -------------------------------- ### ISO13584_expressions_schema Table A1 Short Name Update Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part20/P20/Part20-IS/Released-Part20-IS/P20IS_RN.txt This entry notes that short names are missing for entities in Table A1 of the ISO13584-20:1998 document, specifically for entities whose names start with letters between 'i' and 'r'. This is planned for a future Technical Committee (TC) update. ```APIDOC ## Table A1 Short Name Update ### Description Addresses missing short names for entities in Table A1, specifically those starting with letters 'i' through 'r'. ### Method Textual Update (Planned for TC) ### Endpoint N/A (Schema Text Update) ### Parameters N/A ### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) Missing short names to be added in a future TC update. #### Response Example N/A ``` -------------------------------- ### Update Function compatible_content_and_specification Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt The provided snippet for compatible_content_and_specification is incomplete, showing only a partial RETURN statement. ```ruststep RETURN ( ... tab\content_item.dictionary_definition.definition[1] ``` -------------------------------- ### Rust: SyntaxTree Parsing (espr) Source: https://context7.com/ricosjp/ruststep/llms.txt Demonstrates parsing EXPRESS language schemas into an Abstract Syntax Tree (AST) using the `espr` crate's `SyntaxTree` type. Shows conversion to an intermediate representation (IR) and generation of Rust code. ```rust use espr::ast::SyntaxTree; use espr::ir::IR; use espr::codegen::rust::CratePrefix; let express_code = r###" SCHEMA my_schema; ENTITY point; x: REAL; y: REAL; z: REAL; END_ENTITY; ENTITY circle; center: point; radius: REAL; END_ENTITY; TYPE positive_real = REAL; WHERE positive: SELF > 0.0; END_TYPE; END_SCHEMA; "###; // Parse EXPRESS into syntax tree let syntax_tree = SyntaxTree::parse(express_code).expect("Parse failed"); println!("Parsed {} schemas", syntax_tree.schemas.len()); println!("Schema name: {}", syntax_tree.schemas[0].name); println!("Entities: {}", syntax_tree.schemas[0].entities.len()); // Convert to intermediate representation let ir = IR::from_syntax_tree(&syntax_tree).expect("Semantic analysis failed"); // Generate Rust code let rust_code = ir.to_token_stream(CratePrefix::External); println!("{}", rust_code); ``` -------------------------------- ### Parse Entire STEP File Source: https://context7.com/ricosjp/ruststep/llms.txt Parses a complete STEP file into an AST representation. Ensure the file path is correct and the file is readable. ```rust use std::{fs, path::PathBuf}; use ruststep::parser; // Parse a STEP file from disk let step_file = PathBuf::from("model.step"); let step_str = fs::read_to_string(step_file).unwrap(); // Parse the entire exchange structure let exchange = parser::parse(&step_str).unwrap(); // Access the parsed sections println!("Header records: {:?}", exchange.header); println!("Data sections: {}", exchange.data.len()); // Each data section contains entity instances for data_section in &exchange.data { for entity in &data_section.entities { println!("{:?}", entity); } } ``` -------------------------------- ### Dictionary Values for Material Type Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Specifies the dictionary values for material types, such as 'acoustical', 'magnetic', 'optical', and 'thermal-electric'. ```step #220=DIC_VALUE(VALUE_CODE_TYPE('ACO'), #221, $); #221=ITEM_NAMES(LABEL('acoustical'), (), LABEL('acoustical'), $, $); #222=DIC_VALUE(VALUE_CODE_TYPE('MG'), #223, $); #223=ITEM_NAMES(LABEL('magnetic'), (), LABEL('magnetical'), $, $); #224=DIC_VALUE(VALUE_CODE_TYPE('OP'), #225, $); #225=ITEM_NAMES(LABEL('optical'), (), LABEL('optical'), $, $); #226=DIC_VALUE(VALUE_CODE_TYPE('TH'), #227, $); #227=ITEM_NAMES(LABEL('thermal-electric'), (), LABEL('th-electric'), $, $); ``` -------------------------------- ### Initialize Local Attribute in FUNCTION makes_reference_outside Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt Initializes the local attribute 'temp' in the 'makes_reference_outside' function before its first use. ```text FUNCTION makes_reference_outside(...) ... IF NOT (temp[1] IN l) ... ... END_FUNCTION; FUNCTION makes_reference_outside(...) ... temp := data_type_class_of(p[j]); IF NOT (temp[1] IN l) ... ... END_FUNCTION; ``` -------------------------------- ### Implement Applicable Documents Function Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part25/Part25-IS/Released-Part25-IS/P25IS_RN.txt This function determines if documents are applicable to a given class. It handles cases with no documents, undefined classes, and checks for specific schema types. ```text FUNCTION applicable_documents(cl: class_BSU; doc: AGGREGATE OF document_BSU): LOGICAL; IF SIZEOF(doc) = 0 THEN RETURN(TRUE); END_IF; IF NOT EXISTS(cl) THEN RETURN(UNKNOWN); END_IF; IF SIZEOF(cl.definition) = 0 THEN RETURN(UNKNOWN); END_IF; doc := doc - retrieve_documents(cl); IF 'ISO13584_25_IEC61360_5_LIBRARY_IMPLICIT_SCHEMA' + '.A_PRIORI_SEMANTIC_RELATIONSHIP' IN TYPEOF(cl.definition[1]) THEN Doc := doc - cl.definition[1]\a_priori_semantic_relationship. referenced_documents; END_IF; IF SIZEOF(doc) = 0 THEN RETURN(TRUE); ELSE IF EXISTS(cl.definition[1]\class.its_superclass) THEN RETURN(applicable_documents(cl.definition[1] \class.its_superclass, doc)); ELSE RETURN(FALSE); END_IF; END_IF; END_FUNCTION; -- applicable_documents ``` -------------------------------- ### Deserialize STEP Record to Custom Struct Source: https://context7.com/ricosjp/ruststep/llms.txt Demonstrates parsing a STEP AST Record from a string and deserializing it into a custom Rust struct using serde. The struct's `#[serde(rename = ...)]` attribute must match the record name. ```rust use ruststep::ast::{Record, Parameter}; use serde::Deserialize; use std::str::FromStr; // Parse a simple record let record = Record::from_str("POINT(1.0, 2.0, 3.0)").unwrap(); assert_eq!(record.name, "POINT"); // Deserialize record into a custom struct #[derive(Debug, Clone, PartialEq, Deserialize)] #[serde(rename = "POINT")] struct Point { x: f64, y: f64, z: f64, } let point: Point = Point::deserialize(&record).unwrap(); assert_eq!(point, Point { x: 1.0, y: 2.0, z: 3.0 }); // Records can also be deserialized as HashMaps use std::collections::HashMap; let record = Record::from_str("DATA_ITEM(10, 20)").unwrap(); let map: HashMap> = HashMap::deserialize(&record).unwrap(); assert_eq!(map.get("DATA_ITEM"), Some(&vec![10, 20])); ``` -------------------------------- ### Dictionary Values for Tree Type Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Specifies the dictionary values for the tree type, distinguishing between 'MATERIAL' and 'COMPONS'. ```step #120=DIC_VALUE(VALUE_CODE_TYPE('MATERIAL'), #121, $); #121=ITEM_NAMES(LABEL('material tree'), (), LABEL('mat tree'), $, $); #122=DIC_VALUE(VALUE_CODE_TYPE('COMPONS'), #123, $); #123=ITEM_NAMES(LABEL('component tree'), (), LABEL('comp tree'), $, $); ``` -------------------------------- ### Function: Return Key Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt Returns the key of a table variable if it matches the specified schema type. ```text IF 'ISO13584_G_M_IIM_LIBRARY_IMPLICIT_SCHEMA.TABLE_VARIABLE' ... RETURN(t\table_variable.its_key); END_IF; ``` -------------------------------- ### Function: Compatible Content and Specification Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt Compares content and specification definitions, specifically checking the column meaning from the table specification against the table extension content. ```text RETURN ( ... tab\content_item.dictionary_definition.definition[1] \table_specification.column_meaning), tab\table_extension.content)); ``` -------------------------------- ### Material Type Property Definition Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Defines the property for the material type, including its code and value domain. ```step #210=PROPERTY_BSU('AAF311', '005', #100); #211=NON_DEPENDENT_P_DET(#210, #3, '01', #212, TEXT('code of the type of material'), $, $, $, $, (), $, 'A57', #213, $); #212=ITEM_NAMES(LABEL('material type'), (), LABEL('material type'), $, $); #213=NON_QUANTITATIVE_CODE_TYPE('M..3', #214); #214=VALUE_DOMAIN((#220, #222, #224, #226), $, $, ()); ``` -------------------------------- ### Function: Selectable Properties List (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 5 - FUNCTION selectable_properties_list LOCAL i : INTEGER; ``` -------------------------------- ### Update Function return_key Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt Simplified the RETURN statement in return_key to directly reference the table variable's key. ```ruststep RETURN(t\table_variable.its_key); ``` -------------------------------- ### Parsing Header Sections Source: https://context7.com/ricosjp/ruststep/llms.txt Shows how to use the `parse_header` function to extract and parse only the HEADER section of a STEP file, returning structured metadata. ```APIDOC ## Parsing Header Sections ### Description The `parse_header` function extracts and parses just the HEADER section of a STEP file, returning structured metadata about the file. ### Method `ruststep::parser::parse_header` ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use ruststep::parser::parse_header; use ruststep::header::Header; let step_header = r#" HEADER; FILE_DESCRIPTION(('Example CAD Model', 'Generated by MyApp'), '2;1'); FILE_NAME( '/models/part.step', '2024-01-15T10:30:00', ('John Doe', 'ACME Corp'), ('Engineering Department'), 'MyApp v2.0', 'CAD System v4.0', 'Approved by QA' ); FILE_SCHEMA(('AUTOMOTIVE_DESIGN')); ENDSEC; "#.trim(); let (residual, records) = parse_header(step_header).unwrap(); assert_eq!(residual, ""); // All input consumed // Convert raw records to typed Header struct let header = Header::from_records(&records).unwrap(); println!("File name: {}", header.file_name.name); println!("Schema: {:?}", header.file_schema.schema); println!("Authors: {:?}", header.file_name.author); ``` ### Response #### Success Response (200) - **residual** (string) - Any remaining unparsed input. - **records** (Vec) - A vector of parsed header records. #### Response Example ```json { "residual": "", "records": [ { "name": "FILE_DESCRIPTION", "parameters": [...] }, { "name": "FILE_NAME", "parameters": [...] }, { "name": "FILE_SCHEMA", "parameters": [...] } ] } ``` ``` -------------------------------- ### Dictionary Values for Component Main Class Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Specifies the dictionary values for the main functional class of a component, such as 'EE' (electric/electronic), 'electromechanical', 'mechanical', and 'magnetic part'. ```step #320=DIC_VALUE(VALUE_CODE_TYPE('EE'), #321, $); #321=ITEM_NAMES(LABEL('EE (electric / electronic)'), (), LABEL('EE'), $, $); #322=DIC_VALUE(VALUE_CODE_TYPE('EM'), #323, $); #323=ITEM_NAMES(LABEL('electromechanical'), (), LABEL('electromech'), $, $); #324=DIC_VALUE(VALUE_CODE_TYPE('ME'), #325, $); #325=ITEM_NAMES(LABEL('mechanical'), (), LABEL('mechanical'), $, $); #326=DIC_VALUE(VALUE_CODE_TYPE('MP'), #327, $); #327=ITEM_NAMES(LABEL('magnetic part'), (), LABEL('magnetic'), $, $); ``` -------------------------------- ### Function: Return Key (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 11 - FUNCTION return_key LOCAL i : INTEGER; ``` -------------------------------- ### Parse STEP DataSection in Rust Source: https://context7.com/ricosjp/ruststep/llms.txt Demonstrates parsing a STEP file's DATA section into a `DataSection` struct. The struct contains indexed entity instances that can be iterated over. ```rust use ruststep::ast::DataSection; use std::str::FromStr; let input = r#" DATA; #1 = POINT(0.0, 0.0, 0.0); #2 = POINT(1.0, 0.0, 0.0); #3 = LINE(#1, #2); ENDSEC; "#; let data_section = DataSection::from_str(input).unwrap(); // Iterate through entity instances for entity in &data_section.entities { match entity { ruststep::ast::EntityInstance::Simple { id, record } => { println!("#{} = {}(...)", id, record.name); } ruststep::ast::EntityInstance::Complex { id, subsuper } => { println!("#{} = complex entity with {} components", id, subsuper.0.len()); } } } ``` -------------------------------- ### Function: Optional Properties List (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 4 - FUNCTION optional_properties_list LOCAL i : INTEGER; ``` -------------------------------- ### Add Global Rule for Imported Documents Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt This rule ensures that imported documents are correctly recognized and applied based on a priori semantics relationships and document element types. It should be added to the long form of the schema. ```ruststep RULE imported_documents_are_visible_or_applicable_rule FOR ( a_priori_semantics_relationship, document_element); WHERE WR1: QUERY (rel <* a_priori_semantics_relationship | QUERY ( doc <* rel.referenced_documents | QUERY ( cl <* rel.referenced_classes | NOT visible_documents (cl, [doc]) AND NOT applicable_documents (cl, [doc])) = rel.referenced_classes) <> [] ) = []; END_RULE; -- imported_documents_are_visible_or_applicable_rule ``` -------------------------------- ### Import AP203 and AP201 Modules in Rust Source: https://context7.com/ricosjp/ruststep/llms.txt When the corresponding feature flags are enabled, you can import the generated modules for specific Application Protocols. AP203 is for mechanical parts and assemblies, while AP201 is for explicit drafting. ```rust // When ap203 feature is enabled: #[cfg(feature = "ap203")] use ruststep::ap203; // AP203 provides types for "Configuration controlled 3D design // of mechanical parts and assemblies" // AP201 provides types for "Explicit draughting" ``` -------------------------------- ### Parse Various Parameter Types in Rust Source: https://context7.com/ricosjp/ruststep/llms.txt Demonstrates parsing integers, reals, strings, enumerations, lists, and entity references into the Parameter enum. Lists can be deserialized into Vec or custom structs. ```rust use ruststep::ast::Parameter; use serde::Deserialize; use std::str::FromStr; // Parse different parameter types let integer = Parameter::from_str("42").unwrap(); assert_eq!(integer, Parameter::Integer(42)); let real = Parameter::from_str("3.14159").unwrap(); assert_eq!(real, Parameter::Real(3.14159)); let string = Parameter::from_str("'Hello STEP'").unwrap(); assert_eq!(string, Parameter::String("Hello STEP".to_string())); let enumeration = Parameter::from_str(".TRUE.").unwrap(); assert_eq!(enumeration, Parameter::Enumeration("TRUE".to_string())); // Parse a list parameter let list = Parameter::from_str("(1.0, 2.0, 3.0)").unwrap(); // Deserialize list into a Vec let coords: Vec = Vec::deserialize(&list).unwrap(); assert_eq!(coords, vec![1.0, 2.0, 3.0]); // Deserialize list into a struct #[derive(Debug, PartialEq, Deserialize)] struct Vector3 { x: f64, y: f64, z: f64, } let vec3: Vector3 = Vector3::deserialize(&list).unwrap(); assert_eq!(vec3, Vector3 { x: 1.0, y: 2.0, z: 3.0 }); // Parse entity reference let reference = Parameter::from_str("#123").unwrap(); // References are deserialized as enum variants #[derive(Debug, PartialEq, Deserialize)] enum EntityRef { #[serde(rename = "Entity")] E(u64), } let entity_ref: EntityRef = EntityRef::deserialize(&reference).unwrap(); assert_eq!(entity_ref, EntityRef::E(123)); ``` -------------------------------- ### Update Function compliant_http_protocol_24_1 Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt No functional change, but the comment indicates potential tool requirements for the \label attribute. ```ruststep IF ef.designation.short_name\label --some tools may require \label ``` -------------------------------- ### Rust: Complex Entity Instances (External Mapping) Source: https://context7.com/ricosjp/ruststep/llms.txt Handles complex entity instances using external mapping where multiple partial entities are grouped together. Shows parsing of the format '(ENTITY1(...) ENTITY2(...))' and deserialization into a HashMap or a custom struct. ```rust use ruststep::ast::{SubSuperRecord, Record, Parameter}; use serde::Deserialize; use std::str::FromStr; use std::collections::HashMap; // Parse external mapping format: (ENTITY1(...) ENTITY2(...)) let complex = SubSuperRecord::from_str("(PERSON('John') EMPLOYEE(50000))").unwrap(); // Deserialize as a HashMap let map: HashMap> = HashMap::deserialize(&complex).unwrap(); // Or deserialize into a struct with fields for each component #[derive(Debug, Clone, PartialEq, Deserialize)] struct PersonEmployee { #[serde(rename = "PERSON")] person: Vec, #[serde(rename = "EMPLOYEE")] employee: Vec, } let pe: PersonEmployee = PersonEmployee::deserialize(&complex).unwrap(); assert_eq!(pe.person, vec!["John".to_string()]); assert_eq!(pe.employee, vec![50000]); ``` -------------------------------- ### Component Property Definition (AAF267) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Placeholder for another component property definition, identified by AAF267. ```step #330=PROPERTY_BSU('AAF267', '005', #100); ``` -------------------------------- ### Function: Makes Sub List (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'k' of type INTEGER, which has since been removed. ```text 8 - FUNCTION makes_sub_list LOCAL k : INTEGER; ``` -------------------------------- ### Implement Retrieve Documents Function Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part25/Part25-IS/Released-Part25-IS/P25IS_RN.txt This function retrieves associated documents for a given class, specifically looking for CLASS_DOCUMENT_RELATIONSHIP types. ```text FUNCTION retrieve_documents(cl: class_BSU): SET[0:?] OF document_BSU; -- requires: { SIZEOF(cl.definition) <> O } LOCAL s: SET[0:?] OF document_BSU := []; END_LOCAL; REPEAT i := 1 TO SIZEOF(cl.definition[1]\class.associated_items); IF 'ISO13584_25_IEC61360_5_LIBRARY_IMPLICIT_SCHEMA' + '.CLASS_DOCUMENT_RELATIONSHIP' IN TYPEOF(cl.definition[1]\class.associated_items[i]) THEN s := s+ cl.definition[1]\class.associated_items[i] \class_document_relationship.related_tokens; END_IF; END_REPEAT; RETURN(s); END_FUNCTION; -- retrieve_documents ``` -------------------------------- ### Function: Retrieve Required Properties (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 2 - FUNCTION retrieve_required_properties LOCAL i: INTEGER; ``` -------------------------------- ### Add applicable_documents and retrieve_documents functions Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_3_RN.txt Adds two new functions, `applicable_documents` and `retrieve_documents`, to the liim_24_3 schema as a consequence of ISSUE NUMBER 2. ```APIDOC ## Add applicable_documents and retrieve_documents functions ### Description As a consequence of ISSUE NUMBER 2, the following functions must be added to the liim_24_3 schema: `applicable_documents` and `retrieve_documents`. ### Method N/A (Schema modification) ### Endpoint N/A (Schema modification) ### Parameters N/A ### Request Example N/A ### Response N/A ### Function Definitions **FUNCTION applicable_documents** ``` FUNCTION applicable_documents ( cl: class_BSU; doc: AGGREGATE OF document_BSU): LOGICAL; IF SIZEOF(doc) = 0 THEN RETURN(TRUE); END_IF; IF NOT EXISTS(cl) THEN RETURN(UNKNOWN); END_IF; IF SIZEOF(cl.definition) = 0 THEN RETURN(UNKNOWN); END_IF; doc := doc - retrieve_documents (cl); IF 'ISO13584_F_V_IIM_LIBRARY_IMPLICIT_SCHEMA.A_PRIORI_SEMANTICS_RELATIONSHIP' IN TYPEOF(cl.definition[1]) THEN doc:= doc- cl.definition[1]\a_priori_semantics_relationship.referenced_documents; END_IF; IF SIZEOF(doc) = 0 THEN RETURN(TRUE); ELSE IF EXISTS(cl.definition[1]\class.its_superclass) THEN RETURN (applicable_documents(cl.definition[1] \class.its_superclass, doc)); ELSE RETURN(FALSE); END_IF; END_IF; END_FUNCTION; -- applicable_documents ``` **FUNCTION retrieve_documents** ``` FUNCTION retrieve_documents (cl: class_BSU): SET[0:?] OF document_BSU; -- requires: { SIZEOF (cl.definition) <> O } LOCAL s: SET[0:?] OF document_BSU; END_LOCAL; s := []; REPEAT i := 1 TO SIZEOF(cl.definition[1]\class.associated_items); IF 'ISO13584_F_M_IIM_LIBRARY_IMPLICIT_SCHEMA'+ '.CLASS_DOCUMENT_RELATIONSHIP' IN TYPEOF(cl.definition[1]\class.associated_items[i]) THEN s := s+ cl.definition[1]\class.associated_items[i] \class_document_relationship.related_tokens; END_IF; END_REPEAT; RETURN(s); END_FUNCTION; -- retrieve_documents ``` ``` -------------------------------- ### Function: Collects Assigned Instance Properties (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 12 - FUNCTION collects_assigned_instance_properties ``` -------------------------------- ### Supplier Data Definition Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Defines supplier-specific data, including a supplier business set unit and associated organization and address. ```step #1=SUPPLIER_BSU('112/2///61360_4_1', *); /*according to ISO 13584-26*/ #2=SUPPLIER_ELEMENT(#1, #3, '01', #4, #5); #3=DATES('1994-09-16', '1994-09-16', $); #4=ORGANIZATION('IEC', 'IEC Maintenance Agency', 'The IEC Maintenance Agency as described in IEC 61360-3: "Maintenance and Validation Procedures"'); #5=ADDRESS('to be determined', $, $, $, $, $, $, $, $, $, $, $); ``` ```step #10=SUPPLIER_BSU('112/3///_00', *); /* ISO/IEC ICS */ ``` -------------------------------- ### Function: Derived Properties List (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 1 - FUNCTION derived_properties_list LOCAL i: INTEGER; ``` -------------------------------- ### Entity: Supplier Program Library Relationship Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt Defines a relationship between a supplier and a program library, specifying the related tokens as a set of program library basic semantic units. ```text SELF\supplier_bsu_relationship.related_tokens : SET[01:?] OF program_library_bsu; ``` -------------------------------- ### Update Function is_SQL_mappable_table_expression Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt Modified the RETURN statement in is_SQL_mappable_table_expression to correctly reference table expressions and conditions. ```ruststep RETURN (is_SQL_mappable_table_expression( arg\select_expression.from_table) AND is_SQL_mappable( arg\select_expression.condition)); ``` -------------------------------- ### Function: Used Variables in Domain (2) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt Collects used variables within a domain's guard clause, specifically when the guard is a boolean expression. ```text IF 'ISO13584_F_M_IIM_LIBRARY_IMPLICIT_SCHEMA.BOOLEAN_EXPRESSION' ... result := result + used_variables(arg.domains[i].guard\boolean_expression); ``` -------------------------------- ### Implement Applicable Documents Function Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_3_RN.txt This function determines if a set of documents is applicable to a given class, recursively checking superclasses if necessary. It's used in conjunction with document visibility rules. ```rust FUNCTION applicable_documents (cl: class_BSU; doc: AGGREGATE OF document_BSU): LOGICAL; IF SIZEOF(doc) = 0 THEN RETURN(TRUE); END_IF; IF NOT EXISTS(cl) THEN RETURN(UNKNOWN); END_IF; IF SIZEOF(cl.definition) = 0 THEN RETURN(UNKNOWN); END_IF; doc := doc - retrieve_documents (cl); IF 'ISO13584_F_V_IIM_LIBRARY_IMPLICIT_SCHEMA.A_PRIORI_SEMANTICS_RELATIONSHIP' IN TYPEOF(cl.definition[1]) THEN doc:= doc- cl.definition[1]\a_priori_semantics_relationship.referenced_documents; END_IF; IF SIZEOF(doc) = 0 THEN RETURN(TRUE); ELSE IF EXISTS(cl.definition[1]\class.its_superclass) THEN RETURN (applicable_documents(cl.definition[1] \class.its_superclass, doc)); ELSE RETURN(FALSE); END_IF; END_IF; END_FUNCTION; -- applicable_documents ``` -------------------------------- ### Component Root Class Definition Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Defines the root class for the components tree, inheriting from the IEC root class. ```step #300=CLASS_BSU('EEE000', '001', #1); #301=COMPONENT_CLASS(#300, #3, '01', #302, TEXT('root class of the components tree'), $, $, $, #100, (#310, #330, #350), (), $, (#310), (#305), 'COMPONS'); #302=ITEM_NAMES(LABEL('components root class'), (), LABEL('components root'), $, $); #305=CLASS_VALUE_ASSIGNMENT(#110, 'COMPONS'); ``` -------------------------------- ### ISO13584_expressions_schema 1.1 to 1.2 Update Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part20/P20/Part20-IS/Released-Part20-IS/P20IS_RN.txt This update corrects an error in the 'used_functions' function related to partial instance references. The incorrect reference to 'like_expression.operands' has been changed to 'comparison_expression.operands'. ```APIDOC ## FUNCTION used_functions Update ### Description Fixes an error in the 'used_functions' function concerning partial instance references. ### Method Schema Modification ### Endpoint N/A (Schema Update) ### Parameters N/A ### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) Schema updated to version 1.2. #### Response Example N/A ``` -------------------------------- ### Initialize Local Attribute in Function Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_3_RN.txt This change initializes the local attribute 'temp' within the 'makes_reference_outside' function using 'data_type_class_of'. Previously, 'temp' was uninitialized, potentially leading to errors. ```EXPRESS temp := data_type_class_of(p[j]); ``` -------------------------------- ### Entity: Linked Interface Program Protocol Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt Defines a linked interface program protocol, querying for program libraries that are referenced and whose used protocol does not match the base protocol. ```text wr1 : QUERY(pl <* SELF.link_libraries | (SIZEOF(pl\basic_semantic_unit. referenced_by) > 0) AND (pl\basic_semantic_unit.referenced_by[1]\ dictionary_external_item\external_item.used_protocol <> SELF. base_protocol)) = []; ``` -------------------------------- ### Function: Diff Columns (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 9 - FUNCTION diff_columns LOCAL i : INTEGER; END_LOCAL; ``` -------------------------------- ### Function: Compatible Column and Variable Semantics (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 10 - FUNCTION compatible_column_and_variable_semantics LOCAL i : INTEGER; ``` -------------------------------- ### Function: Acyclic Class Extension Definition (Unused Variable) Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt This function previously declared an unused local variable 'i' of type INTEGER, which has since been removed. ```text 3 - FUNCTION acyclic_class_extension_definition LOCAL i : INTEGER; ``` -------------------------------- ### Correct Function Parameter Type for check_class_type_for_dic_f_view_instance Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part25/Part25-IS/Released-Part25-IS/P25IS_RN.txt This snippet shows the corrected formal parameter type for the 'check_class_type_for_dic_f_view_instance' function, changing 'dic_f_model_instance' to 'dic_f_view_instance'. ```text FUNCTION check_class_type_for_dic_f_view_instance( dic_cl: dic_f_view_instance): LOGICAL; ``` -------------------------------- ### Implement Retrieve Documents Function Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_3_RN.txt This function retrieves documents associated with a class, specifically looking for relationships of type 'CLASS_DOCUMENT_RELATIONSHIP'. It's a helper for the 'applicable_documents' function. ```rust FUNCTION retrieve_documents (cl: class_BSU): SET[0:?] OF document_BSU; -- requires: { SIZEOF (cl.definition) <> O } LOCAL s: SET[0:?] OF document_BSU; END_LOCAL; s := []; REPEAT i := 1 TO SIZEOF(cl.definition[1]\class.associated_items); IF 'ISO13584_F_M_IIM_LIBRARY_IMPLICIT_SCHEMA'+ '.CLASS_DOCUMENT_RELATIONSHIP' IN TYPEOF(cl.definition[1]\class.associated_items[i]) THEN s := s+ cl.definition[1]\class.associated_items[i] \class_document_relationship.related_tokens; END_IF; END_REPEAT; RETURN(s); END_FUNCTION; -- retrieve_documents ``` -------------------------------- ### Function: Collects Columns Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_2_RN.txt Recursively collects columns from a binary generic expression, specifically from its second operand. ```text IF 'ISO13584_G_M_IIM_LIBRARY_IMPLICIT_SCHEMA.SELECT_EXPRESSION'... tRETURN(collects_columns(t\binary_generic_expression.operands[1])); END_IF; ``` -------------------------------- ### Material Root Class Definition Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Defines the root class for the materials tree, inheriting from the IEC root class. ```step #200=CLASS_BSU('AAA218', '001', #1); #201=MATERIAL_CLASS(#200, #3, '01', #202, TEXT('root class of the materials tree'), $, $, $, #100, (#210, #230), (), $, (#210), (#205), 'MATERIAL'); #202=ITEM_NAMES(LABEL('materials root class'), (), LABEL('materials root'), $, $); #205=CLASS_VALUE_ASSIGNMENT(#110, 'MATERIAL'); ``` -------------------------------- ### Update Function Signature: check_class_type_for_dic_f_view_instance Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-IS/Released-Part24-IS/P24IS_RN.txt This change modifies the formal parameter type in the `check_class_type_for_dic_f_view_instance` function from `dic_f_model_instance` to `dic_f_view_instance` to correct a type mismatch. ```SQL FUNCTION check_class_type_for_dic_f_view_instance( dic_cl: dic_f_model_instance): LOGICAL; ``` ```SQL FUNCTION check_class_type_for_dic_f_view_instance( dic_cl: dic_f_view_instance): LOGICAL; ``` -------------------------------- ### Update Function used_tables_in_domain Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part24/Part24-DIS/liim_24_1_RN.txt Adjusted the call to used_table_literals in used_tables_in_domain to pass the correct argument. ```ruststep result := result + used_table_literals(arg.domains[i].guard); ``` -------------------------------- ### Parse STEP Header Section Source: https://context7.com/ricosjp/ruststep/llms.txt Extracts and parses only the HEADER section of a STEP file. This function returns structured metadata. Ensure the input string contains a valid HEADER section. ```rust use ruststep::parser::parse_header; use ruststep::header::Header; let step_header = r#" HEADER; FILE_DESCRIPTION(("Example CAD Model", "Generated by MyApp"), "2;1"); FILE_NAME( '/models/part.step', '2024-01-15T10:30:00', ('John Doe', 'ACME Corp'), ('Engineering Department'), 'MyApp v2.0', 'CAD System v4.0', 'Approved by QA' ); FILE_SCHEMA(("AUTOMOTIVE_DESIGN")); ENDSEC; "#.trim(); let (residual, records) = parse_header(step_header).unwrap(); assert_eq!(residual, ""); // All input consumed // Convert raw records to typed Header struct let header = Header::from_records(&records).unwrap(); println!("File name: {}", header.file_name.name); println!("Schema: {:?}", header.file_schema.schema); println!("Authors: {:?}", header.file_name.author); ``` -------------------------------- ### Main Class of Component Property Definition Source: https://github.com/ricosjp/ruststep/blob/master/schemas/PLIB/Part42/Part42-IS/PhysicalFile_AnnexD5.txt Defines the property for the main functional class to which a component belongs. ```step #310=PROPERTY_BSU('AAE001', '005', #100); #311=NON_DEPENDENT_P_DET(#310, #3, '01', #312, TEXT('Code of the main functional class to which a component belongs'), $, $, $, $, (), $, 'A52', #313, $); #312=ITEM_NAMES(LABEL('main class of component'), (), LABEL('main class'), $, $); #313=NON_QUANTITATIVE_CODE_TYPE('M..3', #314); #314=VALUE_DOMAIN((#320, #322, #324, #326), $, $, ()); ```