1use std::time::Duration;
2
3mod r#impl;
4use iref::Uri;
5pub use r#impl::*;
6pub mod client;
7
8pub trait EncodedStatusMap {
10 type Decoded: StatusMap;
11 type DecodeError: std::error::Error;
12
13 fn decode(self) -> Result<Self::Decoded, Self::DecodeError>;
14}
15
16#[derive(Debug, Default, Clone, Copy)]
17pub struct FromBytesOptions {
18 pub allow_unsecured: bool,
20}
21
22impl FromBytesOptions {
23 pub const ALLOW_UNSECURED: Self = Self {
24 allow_unsecured: true,
25 };
26}
27
28pub trait FromBytes<V>: Sized {
29 type Error: std::error::Error;
30
31 #[allow(async_fn_in_trait)]
32 async fn from_bytes_with(
33 bytes: &[u8],
34 media_type: &str,
35 verification_params: &V,
36 options: FromBytesOptions,
37 ) -> Result<Self, Self::Error>;
38
39 #[allow(async_fn_in_trait)]
40 async fn from_bytes(bytes: &[u8], media_type: &str, verifier: &V) -> Result<Self, Self::Error> {
41 Self::from_bytes_with(bytes, media_type, verifier, FromBytesOptions::default()).await
42 }
43}
44
45#[derive(Debug, thiserror::Error)]
46pub enum StatusSizeError {
47 #[error("missing status size")]
48 Missing,
49
50 #[error("invalid status size")]
51 Invalid,
52}
53
54pub trait StatusMap: Clone {
60 type Key;
62
63 type StatusSize;
65
66 type Status;
68
69 fn time_to_live(&self) -> Option<Duration> {
72 None
73 }
74
75 fn get_by_key(
81 &self,
82 status_size: Option<Self::StatusSize>,
83 key: Self::Key,
84 ) -> Result<Option<Self::Status>, StatusSizeError>;
85
86 fn get_entry<E: StatusMapEntry<Key = Self::Key, StatusSize = Self::StatusSize>>(
88 &self,
89 entry: &E,
90 ) -> Result<Option<Self::Status>, StatusSizeError> {
91 self.get_by_key(entry.status_size(), entry.key())
92 }
93}
94
95pub trait StatusMapEntrySet {
96 type Entry<'a>: StatusMapEntry
97 where
98 Self: 'a;
99
100 fn get_entry(&self, purpose: StatusPurpose<&str>) -> Option<Self::Entry<'_>>;
101}
102
103pub trait StatusMapEntry {
108 type Key;
110
111 type StatusSize;
113
114 fn status_list_url(&self) -> &Uri;
116
117 fn status_size(&self) -> Option<Self::StatusSize>;
129
130 fn key(&self) -> Self::Key;
132}
133
134impl<E: StatusMapEntry> StatusMapEntry for &E {
135 type Key = E::Key;
136 type StatusSize = E::StatusSize;
137
138 fn status_list_url(&self) -> &Uri {
139 E::status_list_url(*self)
140 }
141
142 fn status_size(&self) -> Option<Self::StatusSize> {
143 E::status_size(*self)
144 }
145
146 fn key(&self) -> Self::Key {
147 E::key(*self)
148 }
149}
150
151pub enum StatusPurpose<T = String> {
152 Revocation,
156
157 Suspension,
161
162 Other(T),
164}