1#[cfg(feature = "smallvec")]
2pub mod smallvec;
3#[cfg(feature = "smallvec")]
4pub use smallvec::PoemSmallVec;
5
6#[cfg(feature = "arrayvec")]
7pub mod arrayvec;
8#[cfg(feature = "arrayvec")]
9pub use arrayvec::PoemArrayVec;
10
11#[cfg(feature = "heapless")]
12pub mod heapless;
13#[cfg(feature = "heapless")]
14pub use heapless::PoemHeaplessVec;
15
16pub(crate) mod util;
17
18#[cfg(test)]
19mod tests {
20 use poem_openapi::{registry::MetaSchemaRef, types::Type};
21
22 pub(crate) fn check_openapi_props<T: Type, const MAX: usize>()
23 where <T as Type>::RawElementValueType: Type
24 {
25 match T::schema_ref() {
26 MetaSchemaRef::Inline(box_meta) => {
27 assert_eq!(box_meta.nullable, false);
28 assert_eq!(box_meta.min_items, Some(1));
29 assert_eq!(box_meta.max_items, Some(MAX));
30 assert_eq!(box_meta.min_length, Some(1));
32 assert_eq!(box_meta.max_length, Some(MAX));
33 assert_eq!(box_meta.title, Some(format!("1 to {MAX} items of type {}", <T as Type>::RawElementValueType::name())));
34 },
35 MetaSchemaRef::Reference(s) => {
36 panic!("expected Inline schema, got Reference: {s}");
37 },
38 }
39 }
40
41 #[cfg(feature = "smallvec")]
43 mod smallvec_tests {
44 use crate::PoemSmallVec;
45 use poem_openapi::{registry::MetaSchemaRef, types::{ParseFromParameter, ParseFromJSON, Type}};
46 use serde_json::json;
47
48 #[test]
49 fn specifies_correct_openapi_props() {
50 match PoemSmallVec::<u32, 4>::schema_ref() {
51 MetaSchemaRef::Inline(box_meta) => {
52 assert_eq!(box_meta.nullable, false);
53 assert_eq!(box_meta.min_items, Some(1));
54 assert_eq!(box_meta.max_items, None);
55 assert_eq!(box_meta.min_length, Some(1));
56 assert_eq!(box_meta.max_length, None);
57 assert_eq!(box_meta.title, Some(format!("at least 1 item of type {}", <PoemSmallVec::<u32, 4> as Type>::RawElementValueType::name())));
58 },
59 MetaSchemaRef::Reference(s) => {
60 panic!("expected Inline schema, got Reference: {s}");
61 },
62 }
63 }
64
65 #[test]
66 fn parse_single_element() {
67 let vec = PoemSmallVec::<i32, 4>::parse_from_parameter("42")
68 .expect("should parse single element");
69 assert_eq!(vec.as_slice(), &[42]);
70 }
71
72 #[test]
73 fn parse_multiple_elements() {
74 let input = vec!["1", "2", "3"];
75 let vec = PoemSmallVec::<i32, 4>::parse_from_parameters(input)
76 .expect("should parse multiple elements");
77 assert_eq!(vec.as_slice(), &[1, 2, 3]);
78 }
79
80 #[test]
81 fn parse_invalid_single() {
82 assert!(PoemSmallVec::<i32, 4>::parse_from_parameter("not_a_number").is_err());
83 }
84
85 #[test]
86 fn parse_invalid_multiple() {
87 let input = vec!["10", "xx", "30"];
88 assert!(PoemSmallVec::<i32, 4>::parse_from_parameters(input).is_err());
89 }
90
91 #[test]
92 fn parse_json_valid_array() {
93 let value = json!([1, 2, 3]);
94 let vec = PoemSmallVec::<i32, 4>::parse_from_json(Some(value))
95 .expect("should parse valid JSON array");
96 assert_eq!(vec.as_slice(), &[1, 2, 3]);
97 }
98
99 #[test]
100 fn parse_json_invalid_type() {
101 let value = json!({"not": "an array"});
102 assert!(PoemSmallVec::<i32, 4>::parse_from_json(Some(value)).is_err());
103 }
104 }
105
106 #[cfg(feature = "arrayvec")]
108 mod arrayvec_tests {
109 use crate::PoemArrayVec;
110 use poem_openapi::types::{ParseFromJSON, ParseFromParameter};
111 use serde_json::json;
112
113 #[test]
114 fn specifies_correct_openapi_props() {
115 super::check_openapi_props::<PoemArrayVec<u16, 8>, 8>();
116 }
117
118 #[test]
119 fn parse_array_single_element() {
120 let vec = PoemArrayVec::<i32, 4>::parse_from_parameter("42")
121 .expect("should parse single element");
122 assert_eq!(vec.as_slice(), &[42]);
123 }
124
125 #[test]
126 fn parse_array_multiple_elements() {
127 let input = vec!["1", "2", "3"];
128 let vec = PoemArrayVec::<i32, 4>::parse_from_parameters(input)
129 .expect("should parse multiple elements");
130 assert_eq!(vec.as_slice(), &[1, 2, 3]);
131 }
132
133 #[test]
134 fn parse_invalid_array_single() {
135 assert!(PoemArrayVec::<i32, 4>::parse_from_parameter("not_a_number").is_err());
136 }
137
138 #[test]
139 fn parse_invalid_array_multiple() {
140 let input = vec!["10", "xx", "30"];
141 assert!(PoemArrayVec::<i32, 4>::parse_from_parameters(input).is_err());
142 }
143
144 #[test]
145 fn parse_json_valid_array() {
146 let value = json!([1, 2, 3]);
147 let vec = PoemArrayVec::<i32, 4>::parse_from_json(Some(value))
148 .expect("should parse valid JSON array");
149 assert_eq!(vec.as_slice(), &[1, 2, 3]);
150 }
151
152 #[test]
153 fn parse_json_invalid_type() {
154 let value = json!({"not": "an array"});
155 assert!(PoemArrayVec::<i32, 4>::parse_from_json(Some(value)).is_err());
156 }
157 }
158
159 #[cfg(feature = "heapless")]
161 mod heapless_tests {
162 use crate::PoemHeaplessVec;
163 use poem_openapi::types::{ParseFromParameter, ParseFromJSON};
164 use serde_json::json;
165
166 #[test]
167 fn specifies_correct_openapi_props() {
168 super::check_openapi_props::<PoemHeaplessVec<u64, 2>, 2>();
169 }
170
171 #[test]
172 fn parse_heapless_single_element() {
173 let vec = PoemHeaplessVec::<i32, 4>::parse_from_parameter("42")
174 .expect("should parse single element");
175 assert_eq!(vec.as_slice(), &[42]);
176 }
177
178 #[test]
179 fn parse_heapless_multiple_elements() {
180 let input = vec!["1", "2", "3"];
181 let vec = PoemHeaplessVec::<i32, 4>::parse_from_parameters(input)
182 .expect("should parse multiple elements");
183 assert_eq!(vec.as_slice(), &[1, 2, 3]);
184 }
185
186 #[test]
187 fn parse_heapless_invalid_single() {
188 assert!(PoemHeaplessVec::<i32, 4>::parse_from_parameter("not_a_number").is_err());
189 }
190
191 #[test]
192 fn parse_heapless_invalid_multiple() {
193 let input = vec!["10", "xx", "30"];
194 assert!(PoemHeaplessVec::<i32, 4>::parse_from_parameters(input).is_err());
195 }
196
197 #[test]
198 fn parse_json_valid_array() {
199 let value = json!([1, 2, 3]);
200 let vec = PoemHeaplessVec::<i32, 4>::parse_from_json(Some(value))
201 .expect("should parse valid JSON array");
202 assert_eq!(vec.as_slice(), &[1, 2, 3]);
203 }
204
205 #[test]
206 fn parse_json_invalid_type() {
207 let value = json!({"not": "an array"});
208 assert!(PoemHeaplessVec::<i32, 4>::parse_from_json(Some(value)).is_err());
209 }
210 }
211}