poem_openapi/types/external/
humantime.rs1use std::{borrow::Cow, time::Duration};
2
3use poem::{http::HeaderValue, web::Field};
4use serde_json::Value;
5
6use crate::{
7 registry::{MetaSchema, MetaSchemaRef},
8 types::{
9 ParseError, ParseFromJSON, ParseFromMultipartField, ParseFromParameter, ParseResult,
10 ToHeader, ToJSON, Type,
11 },
12};
13
14impl Type for Duration {
15 const IS_REQUIRED: bool = true;
16
17 type RawValueType = Self;
18
19 type RawElementValueType = Self;
20
21 fn name() -> Cow<'static, str> {
22 "string_duration".into()
23 }
24
25 fn schema_ref() -> MetaSchemaRef {
26 MetaSchemaRef::Inline(Box::new(MetaSchema::new_with_format("string", "duration")))
27 }
28
29 fn as_raw_value(&self) -> Option<&Self::RawValueType> {
30 Some(self)
31 }
32
33 fn raw_element_iter<'a>(
34 &'a self,
35 ) -> Box<dyn Iterator<Item = &'a Self::RawElementValueType> + 'a> {
36 Box::new(self.as_raw_value().into_iter())
37 }
38}
39
40impl ParseFromJSON for Duration {
41 fn parse_from_json(value: Option<Value>) -> ParseResult<Self> {
42 let value = value.unwrap_or_default();
43 if let Value::String(value) = value {
44 Ok(humantime::parse_duration(&value)?)
45 } else {
46 Err(ParseError::expected_type(value))
47 }
48 }
49}
50
51impl ParseFromParameter for Duration {
52 fn parse_from_parameter(value: &str) -> ParseResult<Self> {
53 humantime::parse_duration(value).map_err(ParseError::custom)
54 }
55}
56
57impl ParseFromMultipartField for Duration {
58 async fn parse_from_multipart(field: Option<Field>) -> ParseResult<Self> {
59 match field {
60 Some(field) => Ok(humantime::parse_duration(&field.text().await?)?),
61 None => Err(ParseError::expected_input()),
62 }
63 }
64}
65
66impl ToJSON for Duration {
67 fn to_json(&self) -> Option<Value> {
68 Some(Value::String(humantime::format_duration(*self).to_string()))
69 }
70}
71
72impl ToHeader for Duration {
73 fn to_header(&self) -> Option<HeaderValue> {
74 HeaderValue::from_str(&humantime::format_duration(*self).to_string()).ok()
75 }
76}