poem_stackvec/
arrayvec.rs1use std::{borrow::Cow, ops::Deref};
2use poem_openapi::{
3 registry::MetaSchemaRef,
4 types::{ParseError, ParseFromJSON, ParseFromParameter, ParseResult, Type},
5};
6use arrayvec::ArrayVec;
7
8use crate::util::fixed_capacity_schema_ref;
9
10#[derive(Debug)]
12pub struct PoemArrayVec<T, const SIZE: usize>(pub ArrayVec<T, SIZE>);
13
14impl<T, const SIZE: usize> PoemArrayVec<T, SIZE> {
15 #[inline]
16 pub fn new() -> Self {
17 PoemArrayVec(ArrayVec::new())
18 }
19 #[inline]
20 pub fn as_slice(&self) -> &[T] {
21 self.0.as_slice()
22 }
23}
24
25impl<T, const SIZE: usize> Default for PoemArrayVec<T, SIZE> {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl<T, const SIZE: usize> Deref for PoemArrayVec<T, SIZE> {
32 type Target = [T];
33
34 #[inline]
35 fn deref(&self) -> &Self::Target {
36 self.0.as_slice()
37 }
38}
39
40impl<T: Type, const SIZE: usize> Type for PoemArrayVec<T, SIZE> {
41 const IS_REQUIRED: bool = <[T; SIZE]>::IS_REQUIRED;
42 type RawValueType = Self;
43 type RawElementValueType = T;
44
45 fn name() -> Cow<'static, str> {
46 <[T; SIZE]>::name()
47 }
48
49 fn schema_ref() -> MetaSchemaRef {
50 fixed_capacity_schema_ref::<T, SIZE>()
51 }
52
53 fn as_raw_value(&self) -> Option<&Self::RawValueType> {
54 Some(self)
55 }
56
57 fn raw_element_iter<'a>(
58 &'a self,
59 ) -> Box<dyn Iterator<Item = &'a Self::RawElementValueType> + 'a> {
60 Box::new(self.0.iter())
61 }
62}
63
64impl<T: ParseFromParameter, const SIZE: usize> ParseFromParameter for PoemArrayVec<T, SIZE> {
65 fn parse_from_parameter(value: &str) -> ParseResult<Self> {
66 let mut arr = ArrayVec::new();
67 parse_param(value, &mut arr)?;
68 Ok(PoemArrayVec(arr))
69 }
70
71 fn parse_from_parameters<I: IntoIterator<Item = A>, A: AsRef<str>>(
72 iter: I,
73 ) -> ParseResult<Self> {
74 let mut arr = ArrayVec::new();
75 for part in iter {
76 parse_param(part, &mut arr)?;
77 }
78 Ok(PoemArrayVec(arr))
79 }
80}
81
82fn parse_param<S: AsRef<str>, T: ParseFromParameter, const N: usize>(value: S, vec: &mut ArrayVec<T, N>) -> Result<(), ParseError<PoemArrayVec<T, N>>> {
83 let item = T::parse_from_parameter(value.as_ref())
84 .map_err(ParseError::propagate)?;
85 vec.try_push(item)
86 .map_err(|_| ParseError::custom(format!("too many items (max {N})")))?;
87 Ok(())
88}
89
90impl<T: ParseFromJSON, const SIZE: usize> ParseFromJSON for PoemArrayVec<T, SIZE> {
91 fn parse_from_json(value: Option<serde_json::Value>) -> ParseResult<Self> {
92 let value = value.unwrap_or_default();
93 match value {
94 serde_json::Value::Array(arr) => Ok(PoemArrayVec(
95 arr.into_iter()
96 .map(|part| T::parse_from_json(Some(part)).map_err(ParseError::propagate))
97 .collect::<Result<_, _>>()?,
98 )),
99 _ => Err(ParseError::expected_type(value)),
100 }
101 }
102}