systemprompt_provider_contracts/
component.rs1use anyhow::Result;
2use async_trait::async_trait;
3use serde_json::Value;
4
5#[derive(Debug)]
6pub struct ComponentContext<'a> {
7 pub web_config: &'a serde_yaml::Value,
8 pub item: Option<&'a Value>,
9 pub all_items: Option<&'a [Value]>,
10 pub popular_ids: Option<&'a [String]>,
11}
12
13impl<'a> ComponentContext<'a> {
14 #[must_use]
15 pub const fn for_page(web_config: &'a serde_yaml::Value) -> Self {
16 Self {
17 web_config,
18 item: None,
19 all_items: None,
20 popular_ids: None,
21 }
22 }
23
24 #[must_use]
25 pub const fn for_content(
26 web_config: &'a serde_yaml::Value,
27 item: &'a Value,
28 all_items: &'a [Value],
29 popular_ids: &'a [String],
30 ) -> Self {
31 Self {
32 web_config,
33 item: Some(item),
34 all_items: Some(all_items),
35 popular_ids: Some(popular_ids),
36 }
37 }
38
39 #[must_use]
40 pub const fn for_list(web_config: &'a serde_yaml::Value, all_items: &'a [Value]) -> Self {
41 Self {
42 web_config,
43 item: None,
44 all_items: Some(all_items),
45 popular_ids: None,
46 }
47 }
48}
49
50#[derive(Debug)]
51pub struct RenderedComponent {
52 pub html: String,
53 pub variable_name: String,
54}
55
56impl RenderedComponent {
57 #[must_use]
58 pub fn new(variable_name: impl Into<String>, html: impl Into<String>) -> Self {
59 Self {
60 html: html.into(),
61 variable_name: variable_name.into(),
62 }
63 }
64}
65
66#[async_trait]
67pub trait ComponentRenderer: Send + Sync {
68 fn component_id(&self) -> &str;
69
70 fn variable_name(&self) -> &str;
71
72 fn applies_to(&self) -> Vec<String> {
73 vec![]
74 }
75
76 async fn render(&self, ctx: &ComponentContext<'_>) -> Result<RenderedComponent>;
77
78 fn priority(&self) -> u32 {
79 100
80 }
81}