### Parameter Parsing Example Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Example demonstrating parsing a complex nested Parameter structure. ```APIDOC ```rust use nom::Finish; use ruststep::{parser::exchange, ast::{Parameter, Record}}; let (residual, p) = exchange::parameter("B((1.0, A((2.0, 3.0))))") .finish() .unwrap(); assert_eq!(residual, ""); // A((2.0, 3.0)) let a = Parameter::Typed { keyword: "A".to_string(), parameter: Box::new(vec![Parameter::real(2.0), Parameter::real(3.0)].into()), }; // B((1.0, a)) let b = Parameter::Typed { keyword: "B".to_string(), parameter: Box::new(vec![Parameter::real(1.0), a].into()), }; assert_eq!(p, b); ``` ``` -------------------------------- ### Example STEP File Structure (ISO-10303-21) Source: https://docs.rs/ruststep This example demonstrates the standard structure of an ISO-10303-21 exchange structure, including HEADER and DATA sections with entities like FILE_DESCRIPTION, FILE_NAME, and geometric definitions. ```step ISO-10303-21; /* start exchange structure */ HEADER; /* start header section */ FILE_DESCRIPTION( ('THIS FILE CONTAINS A SMALL SAMPLE STEP MODEL'), '3;1' ); FILE_NAME( 'EXAMPLE STEP FILE #1', '2013-02-11T15:30:00', ('JOHN DOE', 'ACME INC.', 'METROPOLIS USA'), ('ACME INC. A SUBSIDIARY OF GIANT INDUSTRIES', 'METROPOLIS USA'), 'CIM/STEP VERSION2', 'SUPER CIM SYSTEM RELEASE 4.0', 'APPROVED BY JOE BLOGGS' ); FILE_SCHEMA(('EXAMPLE_GEOMETRY')); ENDSEC; /* end header section */ DATA; /* start data section */ /* The following 13 entities represent a triangular edge loop */ /* cartesian point entity */ #1 = CPT(0.0, 0.0, 0.0); #2 = CPT(0.0, 1.0, 0.0); #3 = CPT(1.0, 0.0, 0.0); /* vertex entity */ #11 = VX(#1); #12 = VX(#2); #13 = VX(#3); /* edge entity */ #16 = ED(#11, #12); #17 = ED(#11, #13); #18 = ED(#13, #12); /* edge logical structure entity */ #21 = ED_STRC(#17, .F.); #22 = ED_STRC(#18, .F.); #23 = ED_STRC(#16, .T.); /* edge loop entity */ #24 = ED_LOOP((#21, #22, #23)); ENDSEC; /* end data section */ END-ISO-10303-21; /* end exchange structure */ ``` -------------------------------- ### Logical Enum Definition and Usage Examples Source: https://docs.rs/ruststep/latest/src/ruststep/primitive/logical.rs.html Demonstrates the definition of the `Logical` enum and provides comprehensive examples of its usage, including default value, conversions from `bool` and `Option`, and the behavior of NOT, AND, OR, and XOR operations. ```rust use serde::{Deserialize, Serialize}; use std::ops::*; /// `LOGICAL` type /// /// ``` /// use ruststep::primitive::Logical; /// /// // Default /// assert_eq!(Logical::default(), Logical::Unknown); /// /// // From /// assert_eq!(Logical::True, true.into()); /// assert_eq!(Logical::False, false.into()); /// /// // From> /// assert_eq!(Logical::True, Some(true).into()); /// assert_eq!(Logical::False, Some(false).into()); /// assert_eq!(Logical::Unknown, None.into()); /// /// // Not /// assert_eq!(Logical::True, !Logical::False); /// assert_eq!(Logical::False, !Logical::True); /// assert_eq!(Logical::Unknown, !Logical::Unknown); /// /// // BitAnd /// assert_eq!(Logical::True & Logical::True, Logical::True); /// assert_eq!(Logical::True & Logical::Unknown, Logical::Unknown); /// assert_eq!(Logical::True & Logical::False, Logical::False); /// assert_eq!(Logical::False & Logical::True, Logical::False); /// assert_eq!(Logical::False & Logical::Unknown, Logical::False); /// assert_eq!(Logical::False & Logical::False, Logical::False); /// assert_eq!(Logical::Unknown & Logical::True, Logical::Unknown); /// assert_eq!(Logical::Unknown & Logical::Unknown, Logical::Unknown); /// assert_eq!(Logical::Unknown & Logical::False, Logical::False); /// /// // BitOr /// assert_eq!(Logical::True | Logical::True, Logical::True); /// assert_eq!(Logical::True | Logical::Unknown, Logical::True); /// assert_eq!(Logical::True | Logical::False, Logical::True); /// assert_eq!(Logical::False | Logical::True, Logical::True); /// assert_eq!(Logical::False | Logical::Unknown, Logical::Unknown); /// assert_eq!(Logical::False | Logical::False, Logical::False); /// assert_eq!(Logical::Unknown | Logical::True, Logical::True); /// assert_eq!(Logical::Unknown | Logical::Unknown, Logical::Unknown); /// assert_eq!(Logical::Unknown | Logical::False, Logical::Unknown); /// /// // BitXor /// assert_eq!(Logical::True ^ Logical::True, Logical::False); /// assert_eq!(Logical::True ^ Logical::Unknown, Logical::Unknown); /// assert_eq!(Logical::True ^ Logical::False, Logical::True); /// assert_eq!(Logical::False ^ Logical::True, Logical::True); /// assert_eq!(Logical::False ^ Logical::Unknown, Logical::Unknown); /// assert_eq!(Logical::False ^ Logical::False, Logical::False); /// assert_eq!(Logical::Unknown ^ Logical::True, Logical::Unknown); /// assert_eq!(Logical::Unknown ^ Logical::Unknown, Logical::Unknown); /// assert_eq!(Logical::Unknown ^ Logical::False, Logical::Unknown); /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)] pub enum Logical { False, Unknown, True, } impl Default for Logical { fn default() -> Logical { Logical::Unknown } } impl std::fmt::Display for Logical { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { match self { Logical::True => f.pad("true"), Logical::Unknown => f.pad("unknown"), Logical::False => f.pad("false"), } } } impl From for Logical { fn from(b: bool) -> Logical { match b { true => Logical::True, false => Logical::False, } } } impl From> for Logical { fn from(option: Option) -> Logical { match option { Some(b) => b.into(), None => Logical::Unknown, } } } impl From for Option { fn from(l: Logical) -> Option { match l { Logical::Unknown => None, _ => Some(l == Logical::True), } } } impl BitAnd for Logical { type Output = Self; fn bitand(self, other: Self) -> Self { match (self, other) { (Logical::False, _) => Logical::False, (_, Logical::False) => Logical::False, (Logical::Unknown, _) => Logical::Unknown, (_, Logical::Unknown) => Logical::Unknown, (Logical::True, Logical::True) => Logical::True, } } } impl BitOr for Logical { type Output = Self; fn bitor(self, other: Self) -> Self { match (self, other) { (Logical::True, _) => Logical::True, (_, Logical::True) => Logical::True, (Logical::Unknown, _) => Logical::Unknown, (_, Logical::Unknown) => Logical::Unknown, (Logical::False, Logical::False) => Logical::False, } } } impl BitXor for Logical { type Output = Logical; fn bitxor(self, other: Self) -> Logical { match (self, other) { (Logical::Unknown, _) => Logical::Unknown, (_, Logical::Unknown) => Logical::Unknown, (Logical::True, Logical::True) => Logical::False, (Logical::False, Logical::False) => Logical::False, _ => Logical::True, } } } ``` -------------------------------- ### From Implementation for PlaceHolder Source: https://docs.rs/ruststep/latest/ruststep/tables/enum.PlaceHolder.html Allows converting a Name directly into a PlaceHolder. This simplifies the creation of PlaceHolder instances when starting with a reference. ```rust impl From for PlaceHolder fn from(rvalue: Name) -> Self ``` -------------------------------- ### Logical Enum Usage Examples Source: https://docs.rs/ruststep/latest/ruststep/primitive/enum.Logical.html Demonstrates default value, conversions from bool and Option, and the behavior of logical NOT, AND, OR, and XOR operations. ```rust use ruststep::primitive::Logical; // Default assert_eq!(Logical::default(), Logical::Unknown); // From assert_eq!(Logical::True, true.into()); assert_eq!(Logical::False, false.into()); // From> assert_eq!(Logical::True, Some(true).into()); assert_eq!(Logical::False, Some(false).into()); assert_eq!(Logical::Unknown, None.into()); // Not assert_eq!(Logical::True, !Logical::False); assert_eq!(Logical::False, !Logical::True); assert_eq!(Logical::Unknown, !Logical::Unknown); // BitAnd assert_eq!(Logical::True & Logical::True, Logical::True); assert_eq!(Logical::True & Logical::Unknown, Logical::Unknown); assert_eq!(Logical::True & Logical::False, Logical::False); assert_eq!(Logical::False & Logical::True, Logical::False); assert_eq!(Logical::False & Logical::Unknown, Logical::False); assert_eq!(Logical::False & Logical::False, Logical::False); assert_eq!(Logical::Unknown & Logical::True, Logical::Unknown); assert_eq!(Logical::Unknown & Logical::Unknown, Logical::Unknown); assert_eq!(Logical::Unknown & Logical::False, Logical::False); // BitOr assert_eq!(Logical::True | Logical::True, Logical::True); assert_eq!(Logical::True | Logical::Unknown, Logical::True); assert_eq!(Logical::True | Logical::False, Logical::True); assert_eq!(Logical::False | Logical::True, Logical::True); assert_eq!(Logical::False | Logical::Unknown, Logical::Unknown); assert_eq!(Logical::False | Logical::False, Logical::False); assert_eq!(Logical::Unknown | Logical::True, Logical::True); assert_eq!(Logical::Unknown | Logical::Unknown, Logical::Unknown); assert_eq!(Logical::Unknown | Logical::False, Logical::Unknown); // BitXor assert_eq!(Logical::True ^ Logical::True, Logical::False); assert_eq!(Logical::True ^ Logical::Unknown, Logical::Unknown); assert_eq!(Logical::True ^ Logical::False, Logical::True); assert_eq!(Logical::False ^ Logical::True, Logical::True); assert_eq!(Logical::False ^ Logical::Unknown, Logical::Unknown); assert_eq!(Logical::False ^ Logical::False, Logical::False); assert_eq!(Logical::Unknown ^ Logical::True, Logical::Unknown); assert_eq!(Logical::Unknown ^ Logical::Unknown, Logical::Unknown); assert_eq!(Logical::Unknown ^ Logical::False, Logical::Unknown); ``` -------------------------------- ### EXPRESS File Schema Example Source: https://docs.rs/ruststep/latest/ruststep/header/struct.FileSchema.html An excerpt from ISO-10303-21:2016(E) illustrating the file_schema entity and schema_name type in EXPRESS. ```plaintext ENTITY file_schema; schema_identifiers : LIST [1:?] OF UNIQUE schema_name; END_ENTITY; TYPE schema_name = STRING(1024); END_TYPE; ``` -------------------------------- ### Handling File Metadata Operations Source: https://docs.rs/ruststep/latest/ruststep/error/type.Result.html Illustrates using `and_then` to chain operations like getting file metadata and then its modification time, handling potential errors. ```APIDOC ## Handling File Metadata Operations ### Description This example demonstrates chaining fallible operations related to file system access using `and_then`. It attempts to get metadata for a path and then retrieve its modification time, showing how errors are handled. ### Method `and_then` ### Example Usage ```rust use std::{io::ErrorKind, path::Path}; // Note: on Windows "/" maps to "C:\" let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified()); assert!(root_modified_time.is_ok()); let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified()); assert!(should_fail.is_err()); assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound); ``` ``` -------------------------------- ### Logical Enum Usage Examples Source: https://docs.rs/ruststep/latest/ruststep/primitive/enum.Logical.html Demonstrates common usage patterns for the Logical enum, including default value, conversions from boolean and Option, and logical operations like NOT, AND, OR, and XOR. ```APIDOC ## Logical ruststep::primitive # Enum Logical Copy item path Source Search Settings Help Summary ```rust pub enum Logical { False, Unknown, True, } ``` Expand description `LOGICAL` type ```rust use ruststep::primitive::Logical; // Default assert_eq!(Logical::default(), Logical::Unknown); // From assert_eq!(Logical::True, true.into()); assert_eq!(Logical::False, false.into()); // From> assert_eq!(Logical::True, Some(true).into()); assert_eq!(Logical::False, Some(false).into()); assert_eq!(Logical::Unknown, None.into()); // Not assert_eq!(Logical::True, !Logical::False); assert_eq!(Logical::False, !Logical::True); assert_eq!(Logical::Unknown, !Logical::Unknown); // BitAnd assert_eq!(Logical::True & Logical::True, Logical::True); assert_eq!(Logical::True & Logical::Unknown, Logical::Unknown); assert_eq!(Logical::True & Logical::False, Logical::False); assert_eq!(Logical::False & Logical::True, Logical::False); assert_eq!(Logical::False & Logical::Unknown, Logical::False); assert_eq!(Logical::False & Logical::False, Logical::False); assert_eq!(Logical::Unknown & Logical::True, Logical::Unknown); assert_eq!(Logical::Unknown & Logical::Unknown, Logical::Unknown); assert_eq!(Logical::Unknown & Logical::False, Logical::False); // BitOr assert_eq!(Logical::True | Logical::True, Logical::True); assert_eq!(Logical::True | Logical::Unknown, Logical::True); assert_eq!(Logical::True | Logical::False, Logical::True); assert_eq!(Logical::False | Logical::True, Logical::True); assert_eq!(Logical::False | Logical::Unknown, Logical::Unknown); assert_eq!(Logical::False | Logical::False, Logical::False); assert_eq!(Logical::Unknown | Logical::True, Logical::True); assert_eq!(Logical::Unknown | Logical::Unknown, Logical::Unknown); assert_eq!(Logical::Unknown | Logical::False, Logical::Unknown); // BitXor assert_eq!(Logical::True ^ Logical::True, Logical::False); assert_eq!(Logical::True ^ Logical::Unknown, Logical::Unknown); assert_eq!(Logical::True ^ Logical::False, Logical::True); assert_eq!(Logical::False ^ Logical::True, Logical::True); assert_eq!(Logical::False ^ Logical::Unknown, Logical::Unknown); assert_eq!(Logical::False ^ Logical::False, Logical::False); assert_eq!(Logical::Unknown ^ Logical::True, Logical::Unknown); assert_eq!(Logical::Unknown ^ Logical::Unknown, Logical::Unknown); assert_eq!(Logical::Unknown ^ Logical::False, Logical::Unknown); ``` ``` -------------------------------- ### Get the description of TokenizeFailed (Deprecated) Source: https://docs.rs/ruststep/latest/ruststep/error/struct.TokenizeFailed.html Returns a string description of the `TokenizeFailed` error. This method is deprecated and users should prefer using the `Display` implementation or `to_string()`. ```rust fn description(&self) -> &str ``` -------------------------------- ### Parsing Nested Parameters in STEP Source: https://docs.rs/ruststep/latest/src/ruststep/ast/mod.rs.html Shows how to parse complex, nested parameters in STEP data, including typed parameters with lists and other nested structures. This example uses the `nom` parser and `Parameter::Typed`. ```rust use nom::Finish; use ruststep::{parser::exchange, ast::Parameter}; let (residual, p) = exchange::parameter("B((1.0, A((2.0, 3.0))))") .finish() .unwrap(); assert_eq!(residual, ""); // A((2.0, 3.0)) let a = Parameter::Typed { keyword: "A".to_string(), parameter: Box::new(vec![Parameter::real(2.0), Parameter::real(3.0)].into()), }; // B((1.0, a)) let b = Parameter::Typed { keyword: "B".to_string(), parameter: Box::new(vec![Parameter::real(1.0), a].into()), }; assert_eq!(p, b); ``` -------------------------------- ### Parse Entity and Value Instance Names Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses entity instance names starting with '#' and value instance names starting with '@'. Both expect a u64 value. Parsing fails on overflow or invalid characters. ```rust #[test] fn instance_name() { let (res, s) = super::entity_instance_name("#18446744073709551615" /* u64::MAX */) .finish() .unwrap(); assert_eq!(res, ""); assert_eq!(s, std::u64::MAX); let (res, s) = super::value_instance_name("@18446744073709551615" /* u64::MAX */) .finish() .unwrap(); assert_eq!(res, ""); assert_eq!(s, std::u64::MAX); // u64 overflow assert!( super::entity_instance_name("#18446744073709551616" /* u64::MAX + 1 */) .finish() .is_err() ); assert!( super::value_instance_name("@18446744073709551616" /* u64::MAX + 1 */) .finish() .is_err() ); // zeros should be ignored let (res, s) = super::entity_instance_name("#001").finish().unwrap(); assert_eq!(res, ""); assert_eq!(s, 1); } ``` -------------------------------- ### Creating a Parameter List from an Iterator Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Shows how to construct a `Parameter::List` variant by collecting an iterator of `Parameter` items. ```rust use ruststep::ast::Parameter; let p: Parameter = [Parameter::real(1.0), Parameter::real(2.0)] .iter() .collect(); assert!(matches!(p, Parameter::List(_))); ``` -------------------------------- ### Parameter Conversions Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Demonstrates how to convert various types into a Parameter. ```APIDOC ## Parameter Conversions This section details the various ways to create a `Parameter` from other types. ### `From` ```rust fn from(original: Name) -> Parameter ``` Converts to this type from the input type `Name`. ### `From` ```rust fn from(original: String) -> Parameter ``` Converts to this type from the input type `String`. ### `From>` ```rust fn from(original: Vec) -> Parameter ``` Converts to this type from the input type `Vec`. ### `From` ```rust fn from(original: f64) -> Parameter ``` Converts to this type from the input type `f64`. ### `From` ```rust fn from(original: i64) -> Parameter ``` Converts to this type from the input type `i64`. ``` -------------------------------- ### PlaceHolderVisitor Visit i64 Source: https://docs.rs/ruststep/latest/src/ruststep/tables.rs.html Handles visiting an i64 during deserialization, converting it into an owned PlaceHolder. ```rust fn visit_i64(self, v: i64) -> ::std::result::Result where E: de::Error, { Ok(PlaceHolder::Owned(T::deserialize(v.into_deserializer())?)) } ``` -------------------------------- ### user_defined_keyword Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a user-defined keyword, which starts with '!' followed by a standard keyword. ```APIDOC ## user_defined_keyword ### Description Parses a user-defined keyword. It is identified by a '!' prefix, followed by a standard keyword. ### Signature `pub fn user_defined_keyword(input: &str) -> ParseResult` ### Example ```rust use ruststep::parser::token::user_defined_keyword; let input = "!USERKEY456"; let result = user_defined_keyword(input).unwrap(); assert_eq!(result.1, "USERKEY456"); ``` ``` -------------------------------- ### constant_value_name Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a constant value name, which starts with '@' followed by a standard keyword. ```APIDOC ## constant_value_name ### Description Parses a constant value name, which starts with '@' followed by a standard keyword. ### Signature `pub fn constant_value_name(input: &str) -> ParseResult` ### Example ```rust use ruststep::parser::token::constant_value_name; let input = "@MY_CONSTANT"; let result = constant_value_name(input).unwrap(); assert_eq!(result.1, "MY_CONSTANT"); ``` ``` -------------------------------- ### into_ok() Source: https://docs.rs/ruststep/latest/ruststep/error/type.Result.html Returns the contained Ok value, but never panics. This is a nightly-only experimental API. ```APIDOC ## pub const fn into_ok(self) -> T ### Description Returns the contained `Ok` value, but never panics. This method is known to never panic on the result types it is implemented for, making it a maintainability safeguard. ### Method `into_ok()` ### Parameters None ### Request Example ```rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` ### Response #### Success Response (T) Returns the contained `Ok` value. #### Response Example ```rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` ``` -------------------------------- ### constant_entity_name Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a constant entity name, which starts with a '#' followed by an uppercase keyword. ```APIDOC ## constant_entity_name ### Description Parses a constant entity name, which starts with a '#' followed by an uppercase keyword. ### Signature `pub fn constant_entity_name(input: &str) -> ParseResult` ``` -------------------------------- ### PlaceHolderVisitor Visit str Source: https://docs.rs/ruststep/latest/src/ruststep/tables.rs.html Handles visiting a string slice during deserialization, converting it into an owned PlaceHolder. ```rust fn visit_str(self, v: &str) -> ::std::result::Result where E: de::Error, { Ok(PlaceHolder::Owned(T::deserialize(v.into_deserializer())?)) } ``` -------------------------------- ### Parameter Equality Comparison Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Explains how to compare Parameter instances for equality. ```APIDOC ## Parameter Equality Comparison This section covers the methods for comparing `Parameter` instances. ### `PartialEq` ```rust fn eq(&self, other: &Parameter) -> bool ``` Tests if `self` and `other` `Parameter` instances are equal. This method is used by the `==` operator. ```rust fn ne(&self, other: &Rhs) -> bool ``` Tests if `self` and `other` are not equal. The default implementation is usually sufficient. ``` -------------------------------- ### Generic Any Trait Implementation Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.AnchorItem.html Provides a way to get the `TypeId` of any type that implements `Any`. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Parse User-Defined Keyword Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a user-defined keyword, which starts with '!' followed by a standard keyword. ```rust pub fn user_defined_keyword(input: &str) -> ParseResult { tuple((char('!'), standard_keyword)) .map(|(_e, name)| name) .parse(input) } ``` -------------------------------- ### PlaceHolderVisitor Visit f64 Source: https://docs.rs/ruststep/latest/src/ruststep/tables.rs.html Handles visiting an f64 during deserialization, converting it into an owned PlaceHolder. ```rust fn visit_f64(self, v: f64) -> ::std::result::Result where E: de::Error, { Ok(PlaceHolder::Owned(T::deserialize(v.into_deserializer())?)) } ``` -------------------------------- ### TableInit Trait Methods Source: https://docs.rs/ruststep/latest/ruststep/tables/trait.TableInit.html This snippet details the methods available on the TableInit trait, including required and provided methods. ```APIDOC ## Trait TableInit ruststep::tables ### Summary ```rust pub trait TableInit: Default { // Required method fn append_data_section(&mut self, section: &DataSection) -> Result<()>; // Provided methods fn from_data_section(section: &DataSection) -> Result { ... } fn from_data_sections(sections: &[DataSection]) -> Result { ... } } ``` ### Required Methods #### fn append_data_section(&mut self, section: &DataSection) -> Result<()> Appends a DataSection to the table. ### Provided Methods #### fn from_data_section(section: &DataSection) -> Result Creates a new table initialized from a single DataSection. #### fn from_data_sections(sections: &[DataSection]) -> Result Creates a new table initialized from multiple DataSections. ``` -------------------------------- ### type_id Implementation for Any Trait Source: https://docs.rs/ruststep/latest/ruststep/header/struct.FileName.html Gets the TypeId of a value, used for runtime type identification. ```rust impl Any for T where T: 'static + ?Sized, fn type_id(&self) -> TypeId ``` -------------------------------- ### enumeration Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses an enumeration literal, which starts with a dot, followed by an uppercase keyword, and ends with a dot. ```APIDOC ## enumeration ### Description Parses an enumeration literal, which starts with a dot, followed by an uppercase keyword, and ends with a dot. ### Signature `pub fn enumeration(input: &str) -> ParseResult` ``` -------------------------------- ### anchor_section Source: https://docs.rs/ruststep/latest/src/ruststep/parser/exchange/anchor.rs.html Parses an anchor section, which starts with 'ANCHOR;', contains an anchor list, and ends with 'ENDSEC;'. ```APIDOC ## anchor_section ### Description Parses a complete anchor section from the input string. ### Signature pub fn anchor_section(input: &str) -> ParseResult> ### Returns A `ParseResult` containing a vector of `Anchor` structs if parsing is successful. ``` -------------------------------- ### tag_name Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a tag name, which starts with an uppercase or lowercase letter followed by zero or more alphanumeric characters. ```APIDOC ## tag_name ### Description Parses a tag name. It begins with an uppercase or lowercase letter, followed by zero or more uppercase letters, lowercase letters, or digits. ### Signature `pub fn tag_name(input: &str) -> ParseResult` ### Example ```rust use ruststep::parser::token::tag_name; let input = "TagName123"; let result = tag_name(input).unwrap(); assert_eq!(result.1, "TagName123"); ``` ``` -------------------------------- ### into_ok Usage (Nightly) Source: https://docs.rs/ruststep/latest/ruststep/error/type.Result.html Returns the contained Ok value, never panics. This API is experimental and requires a nightly Rust toolchain. It serves as a compile-time safeguard against Results that cannot fail. ```rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### Basic Result Usage: Ok Source: https://docs.rs/ruststep/latest/ruststep/error/type.Result.html Demonstrates the basic usage of the Result type when the operation is successful. ```rust let x: Result = Ok(2); assert_eq!(x.unwrap(), 2); ``` -------------------------------- ### standard_keyword Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a standard keyword, which starts with an uppercase letter followed by zero or more uppercase letters or digits. ```APIDOC ## standard_keyword ### Description Parses a standard keyword. It must start with an uppercase letter, followed by zero or more uppercase letters or digits. ### Signature `pub fn standard_keyword(input: &str) -> ParseResult` ### Example ```rust use ruststep::parser::token::standard_keyword; let input = "KEYWORD123"; let result = standard_keyword(input).unwrap(); assert_eq!(result.1, "KEYWORD123"); ``` ``` -------------------------------- ### Parameter::String Usage Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Demonstrates the usage of the String variant for representing string literals. ```APIDOC ### String(String) string literal ##### FromStr ```rust use std::str::FromStr; use ruststep::ast::Parameter; let p = Parameter::from_str("'EXAMPLE STRING'").unwrap(); assert_eq!(p, Parameter::String("EXAMPLE STRING".to_string())); ``` ``` -------------------------------- ### Parse Constant Value Name Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a constant value name, which starts with '@' followed by a standard keyword. ```rust pub fn constant_value_name(input: &str) -> ParseResult { tuple((char('@'), standard_keyword)) .map(|(_sharp, name)| name) .parse(input) } ``` -------------------------------- ### reference_section Source: https://docs.rs/ruststep/latest/src/ruststep/parser/exchange/reference.rs.html Parses a complete reference section, which starts with 'REFERENCE;', contains a list of references, and ends with 'ENDSEC;'. ```APIDOC ## reference_section ### Description Parses a reference section delimited by `REFERENCE;` and `ENDSEC;`, extracting a list of `ReferenceEntry`. ### Signature `pub fn reference_section(input: &str) -> ParseResult>` ### Usage This function is used to parse the entire block defining references in a STEP file. ``` -------------------------------- ### TryFrom Implementation Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Name.html Provides a fallible conversion from one type to another. ```APIDOC ## type Error = Infallible ### Description The type returned in the event of a conversion error. ``` ```APIDOC ## fn try_from(value: U) -> Result>::Error> ### Description Performs the conversion. ### Method `try_from` ### Parameters - **value** (U) - The value to convert. ### Response - `Result>::Error>`: The result of the conversion. ``` -------------------------------- ### Parameter::Typed Usage Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Demonstrates how to construct and parse a Typed Parameter, which represents a keyword followed by a single parameter. ```APIDOC ## Typed Corresponding to `TYPED_PARAMETER` in WSN: ``` TYPED_PARAMETER = KEYWORD "(" PARAMETER ")" . ``` and parser::exchange::typed_parameter. It takes only one `PARAMETER` different from Record, which takes many `PARAMETER`s. ``` SIMPLE_RECORD = KEYWORD "(" [ PARAMETER_LIST ] ")" . ``` ### FromStr ```rust use std::str::FromStr; use ruststep::ast::Parameter; let p = Parameter::from_str("FILE_NAME('ruststep')").unwrap(); assert!(matches!(p, Parameter::Typed { .. })); ``` ### Deserialize ```rust use std::{str::FromStr, collections::HashMap}; use ruststep::ast::*; use serde::Deserialize; // Regarded as a map `{ "A": [1, 2] }` in serde data model let p = Parameter::from_str("A((1, 2))").unwrap(); // Map can be deserialize as a hashmap assert_eq!( HashMap::>::deserialize(&p).unwrap(), maplit::hashmap! { "A".to_string() => vec![1, 2] } ); // Map in serde can be interpreted as Rust field #[derive(Debug, Clone, PartialEq, Deserialize)] struct X { #[serde(rename = "A")] a: Vec, } assert_eq!(X::deserialize(&p).unwrap(), X { a: vec![1, 2] }); ``` Different from Record, deserializing into a struct is not supported: ```rust use std::{str::FromStr, collections::HashMap}; use ruststep::ast::*; use serde::Deserialize; let p = Parameter::from_str("A(1)").unwrap(); #[derive(Debug, Clone, PartialEq, Deserialize)] struct A { x: i32, } assert!(A::deserialize(&p).is_err()); ``` #### Fields §`keyword: String` §`parameter: Box` ``` -------------------------------- ### Parse Exponent Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses the exponent part of a real number, starting with 'E' followed by an optional sign and digits. ```Rust fn exponent(input: &str) -> ParseResult { tuple((char('E'), multispace0, opt(sign), multispace0, digit1)) .map(|(_e, _sp1, sign, _sp2, digit)| { let num: i64 = digit.parse().expect("Failed to parse integer in exponent"); match sign { Some('-') => -num, _ => num, } }) .parse(input) } ``` -------------------------------- ### Recommended Message Style for expect Source: https://docs.rs/ruststep/latest/ruststep/error/type.Result.html When using `expect`, it's recommended to phrase messages to explain why the `Result` is expected to be `Ok`, often using phrases like "should be set by" or "should be available". ```rust let path = std::env::var("IMPORTANT_PATH") .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`"); ``` -------------------------------- ### Get the cause of TokenizeFailed (Deprecated) Source: https://docs.rs/ruststep/latest/ruststep/error/struct.TokenizeFailed.html Retrieves the cause of the `TokenizeFailed` error. This method is deprecated and replaced by `Error::source`. ```rust fn cause(&self) -> Option<&dyn Error> ``` -------------------------------- ### TryInto Implementation Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Name.html Provides a fallible conversion into another type. ```APIDOC ## type Error = >::Error ### Description The type returned in the event of a conversion error. ``` ```APIDOC ## fn try_into(self) -> Result>::Error> ### Description Performs the conversion. ### Method `try_into` ### Response - `Result>::Error>`: The result of the conversion. ``` -------------------------------- ### Parse Tag Name Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a tag name, which starts with an uppercase or lowercase letter, followed by zero or more alphanumeric characters. ```rust pub fn tag_name(input: &str) -> ParseResult { tuple((alt((upper, lower)), many0(alt((upper, lower, digit))))) .map(|(first, tail)| { let head = &[first]; head.iter().chain(tail.iter()).collect() }) .parse(input) } ``` -------------------------------- ### Parameter::List Usage Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Demonstrates the usage of the List variant for representing ordered collections of parameters. ```APIDOC ### List(Vec) List of parameters. This can be non-uniform. ``` -------------------------------- ### Parse Standard Keyword Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a standard keyword, which starts with an uppercase letter followed by zero or more uppercase letters or digits. ```rust pub fn standard_keyword(input: &str) -> ParseResult { tuple((upper, many0(alt((upper, digit))))) .map(|(first, tail)| { let head = &[first]; head.iter().chain(tail.iter()).collect() }) .parse(input) } ``` -------------------------------- ### Collecting into Parameter::List Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Demonstrates how to create a `Parameter::List` from an iterator. ```APIDOC ### FromIterator Create a list as `Parameter::List` from `Iterator` or `Iterator`. ```rust use ruststep::ast::Parameter; let p: Parameter = [Parameter::real(1.0), Parameter::real(2.0)] .iter() .collect(); assert!(matches!(p, Parameter::List(_))); ``` ``` -------------------------------- ### value_instance_name Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses a value instance name, which starts with a '@' followed by digits. Leading zeros are ignored, and the value is converted to a u64. ```APIDOC ## value_instance_name ### Description Parses a value instance name, which starts with a '@' followed by digits. Leading zeros are ignored, and the value is converted to a u64. ### Signature `pub fn value_instance_name(input: &str) -> ParseResult` ``` -------------------------------- ### PartialEq Implementation for ReferenceEntry Source: https://docs.rs/ruststep/latest/ruststep/ast/struct.ReferenceEntry.html Enables comparison of ReferenceEntry instances for equality. ```APIDOC ## impl PartialEq for ReferenceEntry ### fn eq(&self, other: &ReferenceEntry) -> bool Tests for `self` and `other` values to be equal, and is used by `==`. ### fn ne(&self, other: &Rhs) -> bool Tests for `!=`. ``` -------------------------------- ### entity_instance_name Source: https://docs.rs/ruststep/latest/src/ruststep/parser/token.rs.html Parses an entity instance name, which starts with a '#' followed by digits. Leading zeros are ignored, and the value is converted to a u64. ```APIDOC ## entity_instance_name ### Description Parses an entity instance name, which starts with a '#' followed by digits. Leading zeros are ignored, and the value is converted to a u64. ### Signature `pub fn entity_instance_name(input: &str) -> ParseResult` ``` -------------------------------- ### Parameter::Integer Usage Source: https://docs.rs/ruststep/latest/ruststep/ast/enum.Parameter.html Demonstrates the usage of the Integer variant for representing signed 64-bit integers. ```APIDOC ### Integer(i64) Signed integer ##### FromStr ```rust use std::str::FromStr; use ruststep::ast::Parameter; let p = Parameter::from_str("10").unwrap(); assert_eq!(p, Parameter::Integer(10)); let p = Parameter::from_str("-10").unwrap(); assert_eq!(p, Parameter::Integer(-10)); ``` ##### Deserialize ```rust use ruststep::ast::*; use serde::Deserialize; let p = Parameter::Integer(2); let a = i64::deserialize(&p).unwrap(); assert_eq!(a, 2); // can be deserialized as unsigned let a = u64::deserialize(&p).unwrap(); assert_eq!(a, 2); // cannot be deserialized negative integer into unsigned let p = Parameter::Integer(-2); let a = i64::deserialize(&p).unwrap(); assert_eq!(a, -2); assert!(u64::deserialize(&p).is_err()); ``` ``` -------------------------------- ### Parse STEP Comments Source: https://docs.rs/ruststep/latest/src/ruststep/parser/combinator.rs.html Parses a STEP comment, which starts with `/*`, contains any characters except `*` or `*/`, and ends with `*/`. Comments are dropped during parsing. ```rust pub fn comment(input: &str) -> ParseResult { let internal = alt(( none_of("*", tuple((char('*'), peek(not(char('/'))))).map(|(star, _not_slash)| star), )); tuple((tag("/*"), many0(internal), tag("*/"))) .map(|(_start, c, _end)| c.into_iter().collect()) .parse(input) } ``` -------------------------------- ### Mapping Record to a Simple Instance Source: https://docs.rs/ruststep/latest/ruststep/ast/struct.Record.html Explains how `Record` can be deserialized as a struct when the struct name matches the record's keyword, using Serde's `Deserialize` trait. ```APIDOC ## §Mapping to simple instance It is deserialized as a “struct” only when the hint function serde::Deserializer::deserialize_struct is called and the struct name matches to its keyword appears in the exchange structure. See the manual of container attribute in serde for detail. ```rust use std::{str::FromStr, collections::HashMap}; use ruststep::ast::*; use serde::Deserialize; let p = Record::from_str("DATA_KEYWORD(1, 2)").unwrap(); #[derive(Debug, Clone, PartialEq, Deserialize)] #[serde(rename = "DATA_KEYWORD")] // keyword matches struct A { x: i32, y: i32, } assert_eq!( A::deserialize(&p).unwrap(), A { x: 1, y: 2 } ); #[derive(Debug, Clone, PartialEq, Deserialize)] #[serde(rename = "ANOTHER_KEYWORD")] // keyword does not match struct B { x: i32, y: i32, } assert!(B::deserialize(&p).is_err()); ``` ``` -------------------------------- ### header_section Source: https://docs.rs/ruststep/latest/src/ruststep/parser/exchange/header.rs.html Parses the entire header section of a STEP file, which starts with 'HEADER;', contains header entities, and ends with 'ENDSEC;'. ```APIDOC ## header_section ### Description Parses the header section of a STEP file, delimited by `HEADER;` and `ENDSEC;`. It expects zero to three header entities followed by an optional list of header entities. ### Signature `pub fn header_section(input: &str) -> ParseResult>` ### Parameters - `input` (*&str*): The input string slice to parse. ### Returns - `ParseResult>`: A result containing a vector of `Record` if parsing is successful, or an error. ### Example ```rust // Assuming header_section is imported and a valid input string is provided let input = "HEADER;\n#1=HEADER_ENTITY(...);\n#2=HEADER_ENTITY(...);\nENDSEC;"; let result = header_section(input); ``` ```