1use std::path::{Path, PathBuf};
2
3use axum::extract::FromRef;
4
5use crate::easymde::EditorConfig;
6
7pub trait ContextTrait: Clone + Send + Sync + 'static {
9 type Ext: ContextExt<Self>;
10
11 fn names_plural(&self) -> impl Iterator<Item = impl AsRef<str>>;
12 fn editor(&self) -> Option<&EditorConfig>;
13 fn uploads_dir(&self) -> &Path;
14 fn ext(&self) -> &Self::Ext;
15}
16
17#[derive(Debug)]
18pub struct Context<T: ContextExt<Self>> {
19 pub(crate) names_plural: Vec<&'static str>,
20 pub(crate) editor_config: Option<EditorConfig>,
21 pub(crate) uploads_dir: PathBuf,
22 pub(crate) ext: T,
23}
24impl<E: ContextExt<Self>> Clone for Context<E> {
25 fn clone(&self) -> Self {
26 Self {
27 names_plural: self.names_plural.clone(),
28 uploads_dir: self.uploads_dir.clone(),
29 editor_config: self.editor_config.clone(),
30 ext: self.ext.clone(),
31 }
32 }
33}
34impl<E: ContextExt<Self> + 'static> ContextTrait for Context<E> {
35 type Ext = E;
36
37 fn names_plural(&self) -> impl Iterator<Item = impl AsRef<str>> {
38 self.names_plural.iter()
39 }
40 fn editor(&self) -> Option<&EditorConfig> {
41 self.editor_config.as_ref()
42 }
43 fn uploads_dir(&self) -> &Path {
44 &self.uploads_dir
45 }
46 fn ext(&self) -> &E {
47 &self.ext
48 }
49}
50
51impl FromRef<Context<()>> for () {
52 fn from_ref(_input: &Context<()>) -> Self {}
53}
54
55pub trait ContextExt<Ctx>: Clone + Send + Sync {}
56
57impl<Ctx, T: Send + Sync + 'static> ContextExt<Ctx> for T where T: Clone {}