Skip to main content

systemprompt_provider_contracts/
page.rs

1use std::any::Any;
2
3use crate::web_config::WebConfig;
4use anyhow::Result;
5use async_trait::async_trait;
6use serde_json::Value;
7
8pub struct PageContext<'a> {
9    pub page_type: &'a str,
10    pub web_config: &'a WebConfig,
11    content_config: &'a (dyn Any + Send + Sync),
12    db_pool: &'a (dyn Any + Send + Sync),
13    content_item: Option<&'a Value>,
14    all_items: Option<&'a [Value]>,
15}
16
17impl std::fmt::Debug for PageContext<'_> {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        f.debug_struct("PageContext")
20            .field("page_type", &self.page_type)
21            .field("web_config", &"<WebConfig>")
22            .field("content_config", &"<dyn Any>")
23            .field("db_pool", &"<dyn Any>")
24            .field("content_item", &self.content_item.is_some())
25            .field("all_items_count", &self.all_items.map(<[_]>::len))
26            .finish()
27    }
28}
29
30impl<'a> PageContext<'a> {
31    #[must_use]
32    pub fn new(
33        page_type: &'a str,
34        web_config: &'a WebConfig,
35        content_config: &'a (dyn Any + Send + Sync),
36        db_pool: &'a (dyn Any + Send + Sync),
37    ) -> Self {
38        Self {
39            page_type,
40            web_config,
41            content_config,
42            db_pool,
43            content_item: None,
44            all_items: None,
45        }
46    }
47
48    #[must_use]
49    pub const fn with_content_item(mut self, item: &'a Value) -> Self {
50        self.content_item = Some(item);
51        self
52    }
53
54    #[must_use]
55    pub const fn with_all_items(mut self, items: &'a [Value]) -> Self {
56        self.all_items = Some(items);
57        self
58    }
59
60    #[must_use]
61    pub fn content_config<T: 'static>(&self) -> Option<&T> {
62        self.content_config.downcast_ref::<T>()
63    }
64
65    #[must_use]
66    pub fn db_pool<T: 'static>(&self) -> Option<&T> {
67        self.db_pool.downcast_ref::<T>()
68    }
69
70    #[must_use]
71    pub const fn content_item(&self) -> Option<&Value> {
72        self.content_item
73    }
74
75    #[must_use]
76    pub const fn all_items(&self) -> Option<&[Value]> {
77        self.all_items
78    }
79}
80
81#[async_trait]
82pub trait PageDataProvider: Send + Sync {
83    fn provider_id(&self) -> &'static str;
84
85    fn applies_to_pages(&self) -> Vec<String> {
86        vec![]
87    }
88
89    async fn provide_page_data(&self, ctx: &PageContext<'_>) -> Result<Value>;
90
91    fn priority(&self) -> u32 {
92        100
93    }
94}