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