zerodds_types/dynamic/
collection.rs1use alloc::vec;
17
18use super::descriptor::{MemberDescriptor, TypeDescriptor, TypeKind};
19use super::type_::{DynamicType, DynamicTypeInner, DynamicTypeMember};
20
21const ELEMENT_MEMBER: &str = "@element";
23
24#[must_use]
27pub fn sequence_of(element: DynamicType, bound: u32) -> DynamicType {
28 let desc = TypeDescriptor::sequence("seq", element.descriptor().clone(), bound);
29 with_element(desc, element)
30}
31
32#[must_use]
35pub fn array_of(element: DynamicType, dims: alloc::vec::Vec<u32>, name: &str) -> DynamicType {
36 let desc = TypeDescriptor::array(name, element.descriptor().clone(), dims);
37 with_element(desc, element)
38}
39
40fn with_element(desc: TypeDescriptor, element: DynamicType) -> DynamicType {
41 let mut md = MemberDescriptor::new(ELEMENT_MEMBER, 0, element.descriptor().clone());
42 md.index = 0;
43 DynamicType::from_inner(DynamicTypeInner {
44 descriptor: desc,
45 members: vec![DynamicTypeMember {
46 descriptor: md,
47 member_type: element,
48 }],
49 })
50}
51
52#[must_use]
56pub fn resolved_element(ty: &DynamicType) -> Option<&DynamicType> {
57 if matches!(ty.kind(), TypeKind::Sequence | TypeKind::Array) {
58 ty.member_by_index(0).map(|m| m.dynamic_type())
59 } else {
60 None
61 }
62}
63
64#[cfg(test)]
65#[allow(clippy::expect_used, clippy::unwrap_used, clippy::panic)]
66mod tests {
67 use super::*;
68 use crate::dynamic::builder::DynamicTypeBuilderFactory as F;
69
70 #[test]
71 fn sequence_of_struct_retains_element() {
72 let mut b = F::create_struct("E");
73 b.add_struct_member("a", 0, TypeDescriptor::primitive(TypeKind::Int32, "int32"))
74 .unwrap();
75 let elem = b.build().unwrap();
76 let seq = sequence_of(elem, 0);
77 assert_eq!(seq.kind(), TypeKind::Sequence);
78 let re = resolved_element(&seq).expect("resolved element");
79 assert_eq!(re.kind(), TypeKind::Structure);
80 assert_eq!(re.member_count(), 1);
81 }
82
83 #[test]
84 fn scalar_sequence_has_no_resolved_element() {
85 let desc = TypeDescriptor::sequence(
87 "seq",
88 TypeDescriptor::primitive(TypeKind::Int32, "int32"),
89 0,
90 );
91 let ty = F::create_type(desc).unwrap().build().unwrap();
92 assert!(resolved_element(&ty).is_none());
93 }
94}