misskey_api/model/
sort.rs

1use std::fmt::{self, Debug, Display};
2use std::str::FromStr;
3
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5
6#[derive(PartialEq, Eq, Clone, Debug, Copy)]
7pub enum SortOrder<T> {
8    Ascending(T),
9    Descending(T),
10}
11
12impl<T: Display> Display for SortOrder<T> {
13    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14        match self {
15            SortOrder::Ascending(k) => write!(f, "+{}", k),
16            SortOrder::Descending(k) => write!(f, "-{}", k),
17        }
18    }
19}
20
21#[derive(Debug, Clone)]
22pub struct ParseSortOrderError<E> {
23    _priv: InternalParseSortOrderError<E>,
24}
25
26impl<E> std::error::Error for ParseSortOrderError<E>
27where
28    E: std::error::Error + 'static,
29{
30    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
31        self._priv.source()
32    }
33}
34
35impl<E> Display for ParseSortOrderError<E> {
36    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37        self._priv.fmt(f)
38    }
39}
40
41#[derive(Debug, Clone)]
42enum InternalParseSortOrderError<E> {
43    InvalidPrefix,
44    InvalidKey(E),
45}
46
47impl<E> std::error::Error for InternalParseSortOrderError<E>
48where
49    E: std::error::Error + 'static,
50{
51    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
52        match self {
53            InternalParseSortOrderError::InvalidPrefix => None,
54            InternalParseSortOrderError::InvalidKey(err) => Some(err),
55        }
56    }
57}
58
59impl<E> Display for InternalParseSortOrderError<E> {
60    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61        match self {
62            InternalParseSortOrderError::InvalidPrefix => f.write_str("invalid sort order prefix"),
63            InternalParseSortOrderError::InvalidKey(_) => f.write_str("invalid sort key"),
64        }
65    }
66}
67
68impl<T: FromStr> FromStr for SortOrder<T> {
69    type Err = ParseSortOrderError<T::Err>;
70
71    fn from_str(s: &str) -> Result<SortOrder<T>, Self::Err> {
72        fn invalid_key<E>(e: E) -> ParseSortOrderError<E> {
73            ParseSortOrderError {
74                _priv: InternalParseSortOrderError::InvalidKey(e),
75            }
76        }
77
78        if let Some(key) = s.strip_prefix('+') {
79            T::from_str(key)
80                .map_err(invalid_key)
81                .map(SortOrder::Ascending)
82        } else if let Some(key) = s.strip_prefix('-') {
83            T::from_str(key)
84                .map_err(invalid_key)
85                .map(SortOrder::Descending)
86        } else {
87            Err(ParseSortOrderError {
88                _priv: InternalParseSortOrderError::InvalidPrefix,
89            })
90        }
91    }
92}
93
94impl<T: Display> Serialize for SortOrder<T> {
95    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
96    where
97        S: Serializer,
98    {
99        serializer.collect_str(self)
100    }
101}
102
103impl<'de, T> Deserialize<'de> for SortOrder<T>
104where
105    T: FromStr,
106    T::Err: Display,
107{
108    fn deserialize<D>(deserializer: D) -> Result<SortOrder<T>, D::Error>
109    where
110        D: Deserializer<'de>,
111    {
112        String::deserialize(deserializer)?
113            .parse()
114            .map_err(serde::de::Error::custom)
115    }
116}