Skip to content

Latest commit

 

History

History
959 lines (737 loc) · 24.1 KB

File metadata and controls

959 lines (737 loc) · 24.1 KB

OpenSCENARIO-rs API Reference

This document provides comprehensive API documentation for the OpenSCENARIO-rs library, covering all modules, types, and functions.

Table of Contents

  1. Core API
  2. Parser Module
  3. Type System
  4. Catalog System
  5. Expression System
  6. Builder API
  7. Error Types
  8. Utility Functions

Core API

High-Level Functions

The library provides convenient high-level functions for common operations:

pub fn parse_file<P: AsRef<Path>>(path: P) -> Result<OpenScenario>
pub fn parse_str(xml: &str) -> Result<OpenScenario>
pub fn parse_catalog_file<P: AsRef<Path>>(path: P) -> Result<CatalogFile>
pub fn parse_catalog_str(xml: &str) -> Result<CatalogFile>
pub fn serialize_str(scenario: &OpenScenario) -> Result<String>

parse_file()

Parse an OpenSCENARIO file from the filesystem.

Parameters:

  • path: P - File path (anything implementing AsRef<Path>)

Returns:

  • Result<OpenScenario> - Parsed scenario or error

Example:

use openscenario_rs::parse_file;

let scenario = parse_file("scenario.xosc")?;
println!("Author: {}", scenario.file_header.author.as_literal().unwrap());

parse_str()

Parse an OpenSCENARIO document from a string.

Parameters:

  • xml: &str - XML content as string

Returns:

  • Result<OpenScenario> - Parsed scenario or error

Example:

let xml = std::fs::read_to_string("scenario.xosc")?;
let scenario = parse_str(&xml)?;

Document Types

#[derive(Debug, Clone, PartialEq)]
pub enum OpenScenarioDocumentType {
    Scenario,
    Catalog,
    ParameterVariation,
    Unknown,
}

Check document type with:

match scenario.document_type() {
    OpenScenarioDocumentType::Scenario => { /* main scenario */ }
    OpenScenarioDocumentType::Catalog => { /* catalog file */ }
    // ... other types
}

Parser Module

XML Parsing (parser::xml)

Core XML parsing functionality with serde integration.

pub fn parse_from_file<P: AsRef<Path>>(path: P) -> Result<OpenScenario>
pub fn parse_from_str(xml: &str) -> Result<OpenScenario>
pub fn serialize_to_string(scenario: &OpenScenario) -> Result<String>
pub fn serialize_to_file<P: AsRef<Path>>(scenario: &OpenScenario, path: P) -> Result<()>

Validation (parser::validation)

Schema validation against OpenSCENARIO XSD.

pub fn validate_against_schema(xml: &str, schema_path: &str) -> Result<()>
pub fn validate_scenario(scenario: &OpenScenario) -> Result<ValidationReport>

Type System

Core Architecture

graph TD
    A[Value&lt;T&gt; System] --> B[Basic Types]
    A --> C[Complex Types]
    
    B --> D[Double = Value&lt;f64&gt;]
    B --> E[OSString = Value&lt;String&gt;]
    B --> F[UnsignedInt = Value&lt;u32&gt;]
    B --> G[Boolean = Value&lt;bool&gt;]
    
    C --> H[Scenario Types]
    C --> I[Entity Types]
    C --> J[Action Types]
    C --> K[Condition Types]
    
    H --> L[OpenScenario]
    H --> M[Storyboard]
    H --> N[FileHeader]
    
    I --> O[Vehicle]
    I --> P[Pedestrian]
    I --> Q[MiscObject]
    
    J --> R[LongitudinalAction]
    J --> S[LateralAction]
    J --> T[VisibilityAction]
    
    K --> U[SpeedCondition]
    K --> V[DistanceCondition]
    K --> W[TimeOfDayCondition]
Loading

Value System

The core parameterization system supporting literal values and parameter references.

Value Types

pub type Double = Value<f64>;
pub type OSString = Value<String>;
pub type UnsignedInt = Value<u32>;
pub type UnsignedShort = Value<u16>;
pub type Int = Value<i32>;
pub type Boolean = Value<bool>;

Value Methods

impl<T> Value<T> {
    pub fn literal(value: T) -> Self
    pub fn parameter(param_ref: String) -> Self
    pub fn as_literal(&self) -> Option<&T>
    pub fn is_literal(&self) -> bool
    pub fn is_parameter(&self) -> bool
    pub fn parameter_name(&self) -> Option<&str>
}

Example:

use openscenario_rs::types::{Double, OSString};

// Create literal values
let speed = Double::literal(30.0);
let name = OSString::literal("ego_vehicle".to_string());

// Create parameter references
let param_speed = Double::parameter("${TargetSpeed}".to_string());
let param_name = OSString::parameter("${VehicleName}".to_string());

// Access values
if let Some(speed_val) = speed.as_literal() {
    println!("Speed: {} m/s", speed_val);
}

if param_speed.is_parameter() {
    println!("Speed is parameterized: {}", param_speed.parameter_name().unwrap());
}

Scenario Types

OpenScenario

The root document type containing all scenario elements.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct OpenScenario {
    pub file_header: FileHeader,
    pub parameter_declarations: Option<ParameterDeclarations>,
    pub catalog_locations: Option<CatalogLocations>,
    pub road_network: Option<RoadNetwork>,
    pub entities: Option<Entities>,
    pub storyboard: Option<Storyboard>,
}

impl OpenScenario {
    pub fn document_type(&self) -> OpenScenarioDocumentType
    pub fn validate(&self, ctx: &ValidationContext) -> Result<()>
}

FileHeader

Metadata about the OpenSCENARIO file.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FileHeader {
    pub author: OSString,
    pub date: OSString,
    pub description: OSString,
    pub rev_major: UnsignedShort,
    pub rev_minor: UnsignedShort,
}

impl FileHeader {
    pub fn new(author: &str, description: &str) -> Self
    pub fn with_date(mut self, date: &str) -> Self
    pub fn with_revision(mut self, major: u16, minor: u16) -> Self
}

Entity Types

Vehicle

Represents a vehicle entity in the scenario.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Vehicle {
    pub name: OSString,
    pub vehicle_category: VehicleCategory,
    pub properties: Option<VehicleProperties>,
    pub bounding_box: Option<BoundingBox>,
    pub performance: Option<Performance>,
    pub axles: Option<Axles>,
}

impl Vehicle {
    pub fn new(name: &str) -> Self
    pub fn with_category(mut self, category: VehicleCategory) -> Self
    pub fn with_mass(mut self, mass: f64) -> Self
    pub fn with_performance(mut self, max_speed: f64, max_accel: f64, max_decel: f64) -> Self
}

VehicleProperties

Physical properties of a vehicle.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct VehicleProperties {
    pub mass: Option<Double>,
    pub model_3d: Option<OSString>,
    pub model_type: Option<OSString>,
}

Pedestrian

Represents a pedestrian entity in the scenario.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Pedestrian {
    pub name: OSString,
    pub pedestrian_category: PedestrianCategory,
    pub model: OSString,
    pub mass: Double,
    pub bounding_box: Option<BoundingBox>,
    pub properties: Option<PedestrianProperties>,
}

impl Pedestrian {
    pub fn new(name: &str, model: &str) -> Self
    pub fn with_category(mut self, category: PedestrianCategory) -> Self
    pub fn with_mass(mut self, mass: f64) -> Self
}

Action Types

Action

Root action type with all possible action variants.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Action {
    Private(PrivateAction),
    UserDefined(UserDefinedAction),
}

PrivateAction

Actions that target specific entities.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PrivateAction {
    pub entity_ref: OSString,
    pub action_type: PrivateActionType,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PrivateActionType {
    LongitudinalAction(LongitudinalAction),
    LateralAction(LateralAction),
    VisibilityAction(VisibilityAction),
    SynchronizeAction(SynchronizeAction),
    ActivateControllerAction(ActivateControllerAction),
    ControllerAction(ControllerAction),
    TeleportAction(TeleportAction),
    RoutingAction(RoutingAction),
    AppearanceAction(AppearanceAction),
}

LongitudinalAction

Actions affecting longitudinal motion.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum LongitudinalAction {
    SpeedAction(SpeedAction),
    LongitudinalDistanceAction(LongitudinalDistanceAction),
    SpeedProfileAction(SpeedProfileAction),
}

SpeedAction

Action to change entity speed.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SpeedAction {
    pub speed_action_dynamics: TransitionDynamics,
    pub speed_target: SpeedTarget,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum SpeedTarget {
    RelativeTargetSpeed(RelativeTargetSpeed),
    AbsoluteTargetSpeed(AbsoluteTargetSpeed),
}

Condition Types

Condition

Root condition type for triggers.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Condition {
    pub name: OSString,
    pub delay: Option<Double>,
    pub condition_edge: ConditionEdge,
    pub condition_type: ConditionType,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ConditionType {
    ByEntity(ByEntityCondition),
    ByValue(ByValueCondition),
}

SpeedCondition

Condition based on entity speed.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SpeedCondition {
    pub value: Double,
    pub rule: Rule,
    pub direction: Option<DirectionalDimension>,
}

impl SpeedCondition {
    pub fn new(value: f64, rule: Rule) -> Self
    pub fn greater_than(value: f64) -> Self
    pub fn less_than(value: f64) -> Self
    pub fn equal_to(value: f64) -> Self
}

Catalog System

CatalogManager

Main interface for catalog operations.

pub struct CatalogManager {
    // Internal fields
}

impl CatalogManager {
    pub fn new() -> Self
    pub fn with_base_path<P: AsRef<Path>>(base_path: P) -> Self
    
    pub fn discover_and_load_catalogs(&mut self, locations: &CatalogLocations) -> Result<()>
    
    pub fn resolve_vehicle_reference(
        &mut self,
        reference: &VehicleCatalogReference,
        location: &VehicleCatalogLocation,
    ) -> Result<ResolvedCatalog<Vehicle>>
    
    pub fn resolve_controller_reference(
        &mut self,
        reference: &ControllerCatalogReference,
        location: &ControllerCatalogLocation,
    ) -> Result<ResolvedCatalog<Controller>>
    
    pub fn resolve_pedestrian_reference(
        &mut self,
        reference: &PedestrianCatalogReference,
        location: &PedestrianCatalogLocation,
    ) -> Result<ResolvedCatalog<Pedestrian>>
    
    pub fn set_global_parameters(&mut self, parameters: HashMap<String, String>) -> Result<()>
    pub fn parameter_engine(&mut self) -> &mut ParameterSubstitutionEngine
}

CatalogLocations

Specifies where to find catalog files.

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CatalogLocations {
    pub vehicle_catalog: Option<VehicleCatalogLocation>,
    pub controller_catalog: Option<ControllerCatalogLocation>,
    pub pedestrian_catalog: Option<PedestrianCatalogLocation>,
    pub misc_object_catalog: Option<MiscObjectCatalogLocation>,
    pub environment_catalog: Option<EnvironmentCatalogLocation>,
    pub maneuver_catalog: Option<ManeuverCatalogLocation>,
    pub trajectory_catalog: Option<TrajectoryCatalogLocation>,
    pub route_catalog: Option<RouteCatalogLocation>,
}

ResolvedCatalog

Result of catalog reference resolution.

#[derive(Debug, Clone)]
pub struct ResolvedCatalog<T> {
    pub entity: T,
    pub source_file: String,
    pub entry_name: String,
    pub resolved_parameters: HashMap<String, String>,
}

impl<T> ResolvedCatalog<T> {
    pub fn with_parameters(
        entity: T,
        source_file: String,
        entry_name: String,
        parameters: HashMap<String, String>,
    ) -> Self
}

Expression System

Expression Evaluation

pub fn evaluate_expression(
    expression: &str,
    parameters: &HashMap<String, String>,
) -> Result<String>

Supported Operations

  • Arithmetic: +, -, *, /
  • Parentheses: (, )
  • Mathematical functions: sqrt, sin, cos, tan, abs, floor, ceil
  • Constants: pi, e
  • Comparisons: >, <, >=, <=, ==, !=
  • Logical: &&, ||, !

Examples

use openscenario_rs::expression::evaluate_expression;
use std::collections::HashMap;

let params = HashMap::from([
    ("Speed".to_string(), "30.0".to_string()),
    ("Time".to_string(), "5.0".to_string()),
]);

// Basic arithmetic
let result = evaluate_expression("${Speed} * ${Time}", &params)?;
assert_eq!(result, "150.0");

// Mathematical functions
let result = evaluate_expression("sqrt(${Speed} * ${Speed} + 100)", &params)?;

// Complex expressions
let result = evaluate_expression("sin(${Speed} * pi / 180) * 100", &params)?;

Builder API

Note: Available only with the builder feature enabled.

Implementation Status

Current Status: 99% functional implementation with 87% compilation success

  • Complete Feature Set: All 6 development sprints implemented
  • Major Compilation Issues Resolved: 30+ errors → 4 remaining lifetime issues
  • 🔄 Final Phase: Resolving fluent API method chaining lifetime variance

ScenarioBuilder

Type-safe fluent API for programmatic scenario construction with state transitions.

#[cfg(feature = "builder")]
pub struct ScenarioBuilder<State = Empty> {
    // Internal state with type-level state tracking
}

// State Types
pub struct Empty;
pub struct HasHeader;
pub struct HasEntities;

impl ScenarioBuilder<Empty> {
    pub fn new() -> ScenarioBuilder<Empty>
    pub fn with_header(self, name: &str, author: &str) -> ScenarioBuilder<HasHeader>
}

impl ScenarioBuilder<HasHeader> {
    // Parameters
    pub fn add_parameter(self, name: &str, param_type: ParameterType, value: &str) -> Self
    pub fn add_parameter_with_constraints(self, name: &str, param_type: ParameterType, value: &str) -> ParameterBuilder<Self>
    
    // Catalog locations  
    pub fn with_catalog_locations(self) -> CatalogLocationsBuilder<Self>
    
    // Road network
    pub fn with_road_file(self, path: &str) -> Self
    
    // Entities
    pub fn with_entities(self) -> ScenarioBuilder<HasEntities>
}

impl ScenarioBuilder<HasEntities> {
    // Entity builders
    pub fn add_vehicle(self, name: &str) -> VehicleBuilder<Self>
    pub fn add_catalog_vehicle(self, name: &str) -> CatalogVehicleBuilder<Self>
    pub fn add_pedestrian(self, name: &str) -> PedestrianBuilder<Self>
    
    // Storyboard
    pub fn with_storyboard(self) -> StoryboardBuilder<Self>
    
    // Build final scenario
    pub fn build(self) -> Result<OpenScenario, BuilderError>
}

Entity Builders

VehicleBuilder

pub struct VehicleBuilder<P> {
    parent: P,
    vehicle_data: VehicleData,
}

impl<P> VehicleBuilder<P> {
    pub fn car(self) -> Self                    // Preset: passenger car
    pub fn truck(self) -> Self                  // Preset: truck
    pub fn with_dimensions(self, length: f64, width: f64, height: f64) -> Self
    pub fn with_mass(self, mass: f64) -> Self
    pub fn with_performance(self, max_speed: f64, max_accel: f64, max_decel: f64) -> Self
    pub fn finish(self) -> P                    // Return to parent builder
}

CatalogVehicleBuilder

pub struct CatalogVehicleBuilder<P> {
    parent: P,
    catalog_ref: CatalogReferenceData,
}

impl<P> CatalogVehicleBuilder<P> {
    pub fn from_catalog(self, catalog_name: &str) -> Self
    pub fn entry_name(self, entry: &str) -> Self
    pub fn parameter_assignments(self) -> ParameterAssignmentBuilder<Self>
    pub fn finish(self) -> P
}

Action Builders

SpeedActionBuilder

pub struct SpeedActionBuilder<P> {
    parent: P,
    action_data: SpeedActionData,
}

impl<P> SpeedActionBuilder<P> {
    pub fn named(self, name: &str) -> Self
    pub fn to_speed(self, speed: f64) -> Self              // Absolute target speed
    pub fn to_speed_parameter(self, param: &str) -> Self   // Parameter reference
    pub fn change_by(self, delta: f64) -> Self             // Relative speed change
    pub fn with_dynamics(self) -> DynamicsBuilder<Self>    // Transition dynamics
    pub fn triggered_by(self) -> TriggerBuilder<Self>      // Trigger conditions
    pub fn finish(self) -> Result<P, BuilderError>
}

TeleportActionBuilder

pub struct TeleportActionBuilder<P> {
    parent: P,
    position_data: Option<PositionData>,
}

impl<P> TeleportActionBuilder<P> {
    pub fn named(self, name: &str) -> Self
    pub fn to(self) -> PositionBuilder<Self>              // Position target
    pub fn triggered_by(self) -> TriggerBuilder<Self>     // Trigger conditions  
    pub fn finish(self) -> Result<P, BuilderError>
}

Position Builders

PositionBuilder

pub trait PositionBuilder<P> {
    fn world_position(self, x: f64, y: f64, z: f64) -> P
    fn lane_position(self, road_id: &str, lane_id: &str, s: f64) -> P
    fn relative_world_position(self, entity: &str, dx: f64, dy: f64, dz: f64) -> P
    fn relative_lane_position(self, entity: &str, ds: f64, dt: f64) -> P
}

Condition Builders

TriggerBuilder

pub struct TriggerBuilder<P> {
    parent: P,
    conditions: Vec<ConditionGroup>,
}

impl<P> TriggerBuilder<P> {
    pub fn time_condition(self, time: f64) -> Self
    pub fn speed_condition(self, entity: &str, speed: f64) -> Self
    pub fn distance_condition(self, entity: &str) -> DistanceConditionBuilder<Self>
    
    pub fn add_condition_group(self) -> ConditionGroupBuilder<Self>
    pub fn finish(self) -> P
}

DistanceConditionBuilder

pub struct DistanceConditionBuilder<P> {
    parent: P,
    entity: String,
    target: Option<PositionOrEntity>,
    rule: Option<Rule>,
}

impl<P> DistanceConditionBuilder<P> {
    pub fn to_entity(self, entity: &str) -> Self
    pub fn to_position(self, position: Position) -> Self
    pub fn closer_than(self, distance: f64) -> Self
    pub fn farther_than(self, distance: f64) -> Self
    pub fn finish(self) -> P
}

Storyboard Builders

⚠️ Note: Current implementation has 4 lifetime variance issues in method chaining

StoryboardBuilder

pub struct StoryboardBuilder<P> {
    parent: P,
    stories: Vec<Story>,
}

impl<P> StoryboardBuilder<P> {
    pub fn add_story(self, name: &str) -> StoryBuilder<Self>
    pub fn finish(self) -> P
}

StoryBuilder (⚠️ Lifetime issues)

pub struct StoryBuilder<'parent, P> {
    parent: &'parent mut StoryboardBuilder<P>,
    story_data: StoryData,
}

impl<'parent, P> StoryBuilder<'parent, P> {
    // ⚠️ These methods have lifetime variance issues:
    pub fn add_act(&mut self, name: &str) -> ActBuilder<'_, Self>
    pub fn finish(self) -> &'parent mut StoryboardBuilder<P>
}

Current Workaround:

// Instead of fluent chaining, use explicit variables:
let mut story_builder = storyboard.add_story("main");
let mut act_builder = story_builder.add_act("phase1");
let maneuver_builder = act_builder.add_maneuver("action", "ego");
let completed = maneuver_builder.finish().finish().finish();

Error Handling

BuilderError

#[derive(Error, Debug)]
pub enum BuilderError {
    #[error("Missing required field: {field}")]
    MissingField { field: String, suggestion: Option<String> },
    
    #[error("Validation error: {message}")]  
    ValidationError { message: String, suggestion: Option<String> },
    
    #[error("Type mismatch: expected {expected}, found {found}")]
    TypeMismatch { expected: String, found: String },
    
    #[error("Entity not found: {entity}")]
    EntityNotFound { entity: String },
    
    #[error("Parameter error: {param} = {value}")]
    ParameterError { param: String, value: String },
}

Example Usage

Basic Scenario

#[cfg(feature = "builder")]
use openscenario_rs::builder::ScenarioBuilder;
use openscenario_rs::types::enums::ParameterType;

let scenario = ScenarioBuilder::new()
    .with_header("Highway Test", "Test Author") 
    .add_parameter("target_speed", ParameterType::Double, "30.0")
    .with_entities()
        .add_vehicle("ego")
            .car()
            .with_dimensions(4.5, 1.8, 1.4)
            .finish()
        .add_vehicle("target")
            .car()
            .finish()
    .with_storyboard()
        .add_story("main_story")
            // Note: Use workaround for method chaining due to lifetime issues
            // .add_act("acceleration") // <-- Currently has lifetime variance error
        .finish()
    .build()?;

With Catalog Integration

let scenario = ScenarioBuilder::new()
    .with_header("Catalog Demo", "Developer")
    .with_catalog_locations()
        .vehicle_catalog("./catalogs/VehicleCatalog.xosc")
        .finish()
    .with_entities()
        .add_catalog_vehicle("ego")
            .from_catalog("VehicleCatalog")
            .entry_name("BMW_X5")
            .parameter_assignments()
                .assign("color", "blue")
                .finish()
            .finish()
    .build()?;

Compilation Status

# Check current builder compilation status
cargo check --features builder

# Current: 4 lifetime variance errors in storyboard method chaining
# Status: 87% resolution rate (30+ errors → 4 remaining)
# Functionality: 99% feature-complete implementation

Error Types

Error Enum

#[derive(Error, Debug)]
pub enum Error {
    #[error("XML parsing error: {0}")]
    XmlParseError(#[from] quick_xml::DeError),
    
    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error),
    
    #[error("Validation error in field '{field}': {message}")]
    ValidationError { field: String, message: String },
    
    #[error("Parameter error for '{param}': {value}")]
    ParameterError { param: String, value: String },
    
    #[error("Entity not found: {entity}")]
    EntityNotFound { entity: String },
    
    #[error("Catalog entry not found: {entry} in catalog {catalog}")]
    CatalogNotFound { catalog: String, entry: String },
    
    #[error("Catalog error: {0}")]
    CatalogError(String),
}

Error Creation

impl Error {
    pub fn with_context(self, context: &str) -> Self
    pub fn parsing_error(msg: &str, line: usize, col: usize) -> Self
    pub fn parameter_error(param: &str, value: &str) -> Self
    pub fn validation_error(field: &str, message: &str) -> Self
    pub fn catalog_error(message: &str) -> Self
}

Result Type

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

Utility Functions

Parameter Management

pub fn extract_scenario_parameters(
    parameter_declarations: &Option<ParameterDeclarations>,
) -> HashMap<String, String>

Extract parameters from scenario parameter declarations.

Validation Traits

pub trait Validate {
    fn validate(&self, ctx: &ValidationContext) -> Result<()>;
}

pub trait Resolve<T> {
    fn resolve(&self, ctx: &ParameterContext) -> Result<T>;
}

Context Types

pub struct ValidationContext {
    pub entities: HashMap<String, EntityRef>,
    pub catalogs: HashMap<String, CatalogRef>,
    pub strict_mode: bool,
}

pub struct ParameterContext {
    pub parameters: HashMap<String, String>,
    pub scope: Vec<String>,
}

Feature Flags

The library supports optional features that can be enabled in your Cargo.toml:

[dependencies.openscenario-rs]
version = "0.1.0"
features = ["builder", "validation"]

Available Features

  • builder - Enables the fluent builder API for programmatic scenario construction
  • validation - Adds comprehensive validation capabilities beyond basic parsing

Thread Safety

All types in the library are Send and Sync where appropriate. The CatalogManager is designed for single-threaded use but catalog resolution results can be safely shared between threads.

Memory Management

The library is designed for efficient memory usage:

  • Zero-copy parsing where possible
  • Lazy evaluation of catalog resolution
  • Value optimization to minimize allocations

Compatibility

  • Rust: 1.70.0 or later
  • OpenSCENARIO: 1.3 specification (1.4 support planned)
  • XML: Standards-compliant XML 1.0 with namespace support