openapiv3/
variant_or.rs

1use std::str::FromStr;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
6#[serde(untagged)]
7pub enum VariantOrUnknown<T> {
8    Item(T),
9    Unknown(String),
10}
11
12impl<T> From<String> for VariantOrUnknown<T>
13where
14    T: FromStr,
15{
16    fn from(s: String) -> Self {
17        match T::from_str(&s) {
18            Ok(t) => Self::Item(t),
19            Err(_) => Self::Unknown(s),
20        }
21    }
22}
23
24#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
25#[serde(untagged)]
26pub enum VariantOrUnknownOrEmpty<T> {
27    Item(T),
28    Unknown(String),
29    Empty,
30}
31
32impl<T> VariantOrUnknownOrEmpty<T> {
33    pub fn is_empty(&self) -> bool {
34        match self {
35            VariantOrUnknownOrEmpty::Empty => true,
36            _ => false,
37        }
38    }
39}
40
41impl<T> Default for VariantOrUnknownOrEmpty<T> {
42    fn default() -> Self {
43        VariantOrUnknownOrEmpty::Empty
44    }
45}
46
47impl<T> From<Option<String>> for VariantOrUnknownOrEmpty<T>
48where
49    T: FromStr,
50{
51    fn from(v: Option<String>) -> Self {
52        match v {
53            Some(s) => match T::from_str(&s) {
54                Ok(t) => VariantOrUnknownOrEmpty::Item(t),
55                Err(_) => VariantOrUnknownOrEmpty::Unknown(s),
56            },
57            None => VariantOrUnknownOrEmpty::Empty,
58        }
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use crate::{StringFormat, VariantOrUnknownOrEmpty};
65
66    #[test]
67    fn test_variant_from() {
68        assert_eq!(
69            VariantOrUnknownOrEmpty::<StringFormat>::from(None),
70            VariantOrUnknownOrEmpty::Empty,
71        );
72        assert_eq!(
73            VariantOrUnknownOrEmpty::<StringFormat>::from(Some("date".to_string())),
74            VariantOrUnknownOrEmpty::Item(StringFormat::Date),
75        );
76        assert_eq!(
77            VariantOrUnknownOrEmpty::<StringFormat>::from(Some("yolo".to_string())),
78            VariantOrUnknownOrEmpty::Unknown("yolo".to_string()),
79        );
80    }
81}