1use crate::session::Session;
4
5use std::{rc::Rc, sync::Arc};
6use url::Url;
7
8#[async_trait::async_trait(?Send)]
37pub trait Repo {
38 type Error: 'static;
40
41 async fn fetch<D: Dereference, S: Session>(
43 &self,
44 id: D,
45 session: S,
46 ) -> Result<Option<D::Output>, Self::Error>;
47}
48
49pub trait RepoFactory {
51 type Repo: Repo;
53
54 type Crypto;
56
57 fn build_repo(&self, crypto: Self::Crypto) -> Self::Repo;
59}
60
61pub trait Dereference {
94 type Output: serde::de::DeserializeOwned;
96
97 fn url(&self) -> &Url;
99}
100
101impl<'a, T> Dereference for &'a T
102where
103 T: Dereference,
104{
105 type Output = T::Output;
106
107 fn url(&self) -> &Url {
108 T::url(self)
109 }
110}
111
112impl<'a, T> Dereference for &'a mut T
113where
114 T: Dereference,
115{
116 type Output = T::Output;
117
118 fn url(&self) -> &Url {
119 T::url(self)
120 }
121}
122
123impl<T> Dereference for Box<T>
124where
125 T: Dereference,
126{
127 type Output = T::Output;
128
129 fn url(&self) -> &Url {
130 T::url(self)
131 }
132}
133
134impl<T> Dereference for Rc<T>
135where
136 T: Dereference,
137{
138 type Output = T::Output;
139
140 fn url(&self) -> &Url {
141 T::url(self)
142 }
143}
144
145impl<T> Dereference for Arc<T>
146where
147 T: Dereference,
148{
149 type Output = T::Output;
150
151 fn url(&self) -> &Url {
152 T::url(self)
153 }
154}
155
156#[async_trait::async_trait(?Send)]
157impl<'a, T> Repo for &'a T
158where
159 T: Repo,
160{
161 type Error = T::Error;
162
163 async fn fetch<D: Dereference, S: Session>(
164 &self,
165 id: D,
166 session: S,
167 ) -> Result<Option<D::Output>, Self::Error> {
168 T::fetch(self, id, session).await
169 }
170}
171
172#[async_trait::async_trait(?Send)]
173impl<'a, T> Repo for &'a mut T
174where
175 T: Repo,
176{
177 type Error = T::Error;
178
179 async fn fetch<D: Dereference, S: Session>(
180 &self,
181 id: D,
182 session: S,
183 ) -> Result<Option<D::Output>, Self::Error> {
184 T::fetch(self, id, session).await
185 }
186}
187
188#[async_trait::async_trait(?Send)]
189impl<T> Repo for Box<T>
190where
191 T: Repo,
192{
193 type Error = T::Error;
194
195 async fn fetch<D: Dereference, S: Session>(
196 &self,
197 id: D,
198 session: S,
199 ) -> Result<Option<D::Output>, Self::Error> {
200 T::fetch(self, id, session).await
201 }
202}
203
204#[async_trait::async_trait(?Send)]
205impl<T> Repo for Rc<T>
206where
207 T: Repo,
208{
209 type Error = T::Error;
210
211 async fn fetch<D: Dereference, S: Session>(
212 &self,
213 id: D,
214 session: S,
215 ) -> Result<Option<D::Output>, Self::Error> {
216 T::fetch(self, id, session).await
217 }
218}
219
220#[async_trait::async_trait(?Send)]
221impl<T> Repo for Arc<T>
222where
223 T: Repo,
224{
225 type Error = T::Error;
226
227 async fn fetch<D: Dereference, S: Session>(
228 &self,
229 id: D,
230 session: S,
231 ) -> Result<Option<D::Output>, Self::Error> {
232 T::fetch(self, id, session).await
233 }
234}