misskey_api/model/
id.rs

1use std::cmp::Ordering;
2use std::fmt::{self, Debug, Display};
3use std::hash::{self, Hash};
4use std::marker::PhantomData;
5use std::str::FromStr;
6
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use thiserror::Error;
10
11pub mod aid;
12pub mod meid;
13pub mod object_id;
14
15#[cfg(feature = "aid")]
16type IdImpl = aid::Aid;
17#[cfg(feature = "meid")]
18type IdImpl = meid::Meid;
19#[cfg(feature = "ulid")]
20type IdImpl = ulid_crate::Ulid;
21#[cfg(feature = "objectid")]
22type IdImpl = object_id::ObjectId;
23
24pub struct Id<T: ?Sized> {
25    inner: IdImpl,
26    _marker: PhantomData<fn() -> T>,
27}
28
29impl<T: ?Sized> Id<T> {
30    #[cfg(any(docsrs, feature = "aid"))]
31    #[cfg_attr(docsrs, doc(cfg(feature = "aid")))]
32    pub fn as_aid(&self) -> &aid::Aid {
33        &self.inner
34    }
35
36    #[cfg(any(docsrs, feature = "meid"))]
37    #[cfg_attr(docsrs, doc(cfg(feature = "meid")))]
38    pub fn as_meid(&self) -> &meid::Meid {
39        &self.inner
40    }
41
42    #[cfg(any(docsrs, feature = "ulid"))]
43    #[cfg_attr(docsrs, doc(cfg(feature = "ulid")))]
44    pub fn as_ulid(&self) -> &ulid_crate::Ulid {
45        &self.inner
46    }
47
48    #[cfg(any(docsrs, feature = "objectid"))]
49    #[cfg_attr(docsrs, doc(cfg(feature = "objectid")))]
50    pub fn as_object_id(&self) -> &object_id::ObjectId {
51        &self.inner
52    }
53}
54
55#[cfg(feature = "aid")]
56impl<T: ?Sized> From<Id<T>> for aid::Aid {
57    fn from(id: Id<T>) -> aid::Aid {
58        *id.as_aid()
59    }
60}
61
62#[cfg(feature = "meid")]
63impl<T: ?Sized> From<Id<T>> for meid::Meid {
64    fn from(id: Id<T>) -> meid::Meid {
65        *id.as_meid()
66    }
67}
68
69#[cfg(feature = "ulid")]
70impl<T: ?Sized> From<Id<T>> for ulid_crate::Ulid {
71    fn from(id: Id<T>) -> ulid_crate::Ulid {
72        *id.as_ulid()
73    }
74}
75
76#[cfg(feature = "objectid")]
77impl<T: ?Sized> From<Id<T>> for object_id::ObjectId {
78    fn from(id: Id<T>) -> object_id::ObjectId {
79        *id.as_object_id()
80    }
81}
82
83// `derive` fails to infer correct trait bounds on phantom type parameter,
84// so just implementing it manually
85
86impl<T> Debug for Id<T> {
87    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88        Debug::fmt(&self.inner, f)
89    }
90}
91
92impl<T> PartialOrd for Id<T> {
93    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
94        self.inner.partial_cmp(&other.inner)
95    }
96}
97
98impl<T> Ord for Id<T> {
99    fn cmp(&self, other: &Self) -> Ordering {
100        self.inner.cmp(&other.inner)
101    }
102}
103
104impl<T> PartialEq for Id<T> {
105    fn eq(&self, other: &Self) -> bool {
106        self.inner.eq(&other.inner)
107    }
108}
109
110impl<T> Eq for Id<T> {}
111
112impl<T> Clone for Id<T> {
113    fn clone(&self) -> Self {
114        Id {
115            inner: self.inner,
116            _marker: PhantomData,
117        }
118    }
119}
120
121impl<T> Copy for Id<T> {}
122
123impl<T> Hash for Id<T> {
124    fn hash<H>(&self, state: &mut H)
125    where
126        H: hash::Hasher,
127    {
128        self.inner.hash(state);
129    }
130}
131
132impl<T> Id<T> {
133    pub fn datetime(&self) -> DateTime<Utc> {
134        self.inner.datetime()
135    }
136}
137
138#[derive(Debug, Error, Clone)]
139#[error("invalid id")]
140pub struct ParseIdError {
141    _priv: (),
142}
143
144impl<T> FromStr for Id<T> {
145    type Err = ParseIdError;
146
147    fn from_str(s: &str) -> Result<Id<T>, Self::Err> {
148        IdImpl::from_str(s)
149            .map(|inner| Id {
150                inner,
151                _marker: PhantomData,
152            })
153            .map_err(|_| ParseIdError { _priv: () })
154    }
155}
156
157impl<T> Display for Id<T> {
158    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159        Display::fmt(&self.inner, f)
160    }
161}
162
163impl<T> Serialize for Id<T> {
164    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165    where
166        S: Serializer,
167    {
168        self.inner.serialize(serializer)
169    }
170}
171
172impl<'de, T> Deserialize<'de> for Id<T> {
173    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
174    where
175        D: Deserializer<'de>,
176    {
177        IdImpl::deserialize(deserializer).map(|inner| Id {
178            inner,
179            _marker: PhantomData,
180        })
181    }
182}