derived_cms/
context.rs

1use std::path::{Path, PathBuf};
2
3use axum::extract::FromRef;
4
5use crate::easymde::EditorConfig;
6
7/// Trait implemented by the context available in all endpoints using [`axum::extract::State`].
8pub 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 {}