Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion autosar_data.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,16 @@ class ContentType:
CharacterData: ContentType
Mixed: ContentType

class ContentMode:
"""
The content mode of an element type
"""
Sequence: ContentMode
Choice: ContentMode
Bag: ContentMode
Characters: ContentMode
Mixed: ContentMode

class Element:
"""
An element in the Autosar data model
Expand Down Expand Up @@ -311,6 +321,8 @@ class ElementType:
"""elements of this type must contain an autosar path in their character data, and have a DEST attribute"""
is_ordered: bool
"""ordered elements may not be sorted, since the sub element order is semantically meaningful"""
content_mode: ContentMode
"""content mode of the element type: Sequence, Choice, Bag, Characters, Mixed"""
splittable: List[AutosarVersion]
"""a list of AutosarVersions in which this element is splittable"""
std_restriction: str
Expand All @@ -321,6 +333,8 @@ class ElementType:
def reference_dest_value(self, target: ElementType) -> EnumItem:
"""helper to determine the correct value for the DEST attribute when setting a reference"""
...
sub_elements_spec: List[SubElementSpec]
"""a list of the specifications of all sub elements allowed on elements of this type"""
def find_sub_element(self, target_name: ElementName, version: VersionSpecification) -> ElementType:
"""find the ElementType of the named sub element in the specification of this ElementType"""
...
Expand Down Expand Up @@ -412,6 +426,15 @@ class AttributeSpec:
required: bool
"""is the attribute required or optional"""

class SubElementSpec:
"""The specification of a sub element"""
element_name: str
"""name of the sub element"""
element_type: ElementType
"""element type of the sub element"""
allowed_versions: List[AutosarVersion]
"""list of versions in which this sub element is compatible"""

class CharacterDataTypeEnum:
"""Character data type: enum"""
values: List[str]
Expand Down Expand Up @@ -451,4 +474,4 @@ __version__: str
"""
Version of the running autosar_data module.
It contains a semver string of the form 'x.y.z'
"""
"""
36 changes: 35 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ struct IncompatibleAttributeValueError {
target_version: AutosarVersion,
}

#[pyclass(frozen)]
#[pyclass(eq, frozen)]
#[derive(Debug, Clone, PartialEq, Eq)]
/// Type of an Element in the specification
struct ElementType(autosar_data_specification::ElementType);

Expand Down Expand Up @@ -142,6 +143,37 @@ struct AttributeSpec {
required: bool,
}

#[pyclass(frozen)]
#[derive(Debug)]
/// Specification of a sub element
struct SubElementSpec {
#[pyo3(get)]
/// name of the sub element
element_name: String,
#[pyo3(get)]
/// element type of the sub element
element_type: ElementType,
#[pyo3(get)]
/// list of versions in which this sub element is compatible
allowed_versions: Vec<AutosarVersion>,
}

#[pyclass(eq, eq_int)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
/// The content mode of an element type
enum ContentMode {
/// Elements of this type contain an ordered sequence of elements
Sequence,
/// Elements of this type contain elements of a single element type chosen from multiple options
Choice,
/// Elements of this type contain a variable amount of unordered elements with different element types chosen from multiple options
Bag,
/// Elements of this type only contain character data
Characters,
/// Elements of this type contain both character data and sub elements
Mixed,
}

#[pyclass]
#[derive(Debug)]
/// The character data in an element or attribute is an enum value
Expand Down Expand Up @@ -441,6 +473,8 @@ fn autosar_data(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<AttributeIterator>()?;
m.add_class::<Attribute>()?;
m.add_class::<AttributeSpec>()?;
m.add_class::<SubElementSpec>()?;
m.add_class::<ContentMode>()?;
m.add_class::<ValidSubElementInfo>()?;
m.add_class::<CharacterDataTypeEnum>()?;
m.add_class::<CharacterDataTypeFloat>()?;
Expand Down
44 changes: 44 additions & 0 deletions src/specification.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::*;
use ::autosar_data_specification;

#[pymethods]
impl ElementType {
Expand All @@ -21,6 +22,17 @@ impl ElementType {
self.0.is_ordered()
}

#[getter]
fn content_mode(&self) -> ContentMode {
match self.0.content_mode() {
autosar_data_specification::ContentMode::Sequence => ContentMode::Sequence,
autosar_data_specification::ContentMode::Choice => ContentMode::Choice,
autosar_data_specification::ContentMode::Bag => ContentMode::Bag,
autosar_data_specification::ContentMode::Characters => ContentMode::Characters,
autosar_data_specification::ContentMode::Mixed => ContentMode::Mixed,
}
}

#[getter]
fn splittable(&self) -> Vec<AutosarVersion> {
let versions = expand_version_mask(self.0.splittable());
Expand All @@ -45,6 +57,24 @@ impl ElementType {
.map(|enumitem| enumitem.to_string())
}

#[getter]
fn sub_elements_spec(&self) -> Vec<SubElementSpec> {
self.0
.sub_element_spec_iter()
.map(|(element_name, element_type, version_mask, _)| {
let versions = expand_version_mask(version_mask)
.iter()
.map(|&ver| AutosarVersion::from(ver))
.collect();
SubElementSpec {
element_name: element_name.to_string(),
element_type: ElementType(element_type),
allowed_versions: versions,
}
})
.collect()
}

fn find_sub_element(
&self,
target_name: &str,
Expand Down Expand Up @@ -112,6 +142,20 @@ impl AttributeSpec {
}
}

#[pymethods]
impl ContentMode {
fn __repr__(&self) -> String {
format!("{self:#?}")
}
}

#[pymethods]
impl SubElementSpec {
fn __repr__(&self) -> String {
format!("{self:?}")
}
}

#[pymethods]
impl CharacterDataTypeEnum {
fn __repr__(&self) -> String {
Expand Down
11 changes: 11 additions & 0 deletions test/specification_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ def test_specification_basic() -> None:
model = AutosarModel()
model.create_file("file")
assert model.root_element.element_type.chardata_spec is None
assert model.root_element.element_type.content_mode == ContentMode.Sequence

el_ar_packages = model.root_element.create_sub_element("AR-PACKAGES")
el_ar_package = el_ar_packages.create_named_sub_element("AR-PACKAGE", "Pkg1")
Expand Down Expand Up @@ -116,3 +117,13 @@ def test_specification_uint() -> None:
assert not cse_spec.__repr__() is None


def test_specification_sub_elements_spec() -> None:
model = AutosarModel()
model.create_file("file")
el_ar_packages = model.root_element.create_sub_element("AR-PACKAGES")
el_pkg = el_ar_packages.create_named_sub_element("AR-PACKAGE", "pkg")
sub_element_spec = el_ar_packages.element_type.sub_elements_spec[0]

assert sub_element_spec.element_name == "AR-PACKAGE"
assert sub_element_spec.element_type == el_pkg.element_type
assert AutosarVersion.AUTOSAR_00050 in sub_element_spec.allowed_versions
Loading