systemprompt_provider_contracts/
component.rs1use std::path::PathBuf;
7
8use async_trait::async_trait;
9use serde_json::Value;
10
11use crate::error::ProviderResult;
12use crate::web_config::WebConfig;
13
14#[derive(Debug, Clone)]
15pub enum PartialSource {
16 Embedded(&'static str),
17 File(PathBuf),
18}
19
20#[derive(Debug, Clone)]
21pub struct PartialTemplate {
22 pub name: String,
23 pub source: PartialSource,
24}
25
26impl PartialTemplate {
27 #[must_use]
28 pub fn embedded(name: impl Into<String>, content: &'static str) -> Self {
29 Self {
30 name: name.into(),
31 source: PartialSource::Embedded(content),
32 }
33 }
34
35 #[must_use]
36 pub fn file(name: impl Into<String>, path: impl Into<PathBuf>) -> Self {
37 Self {
38 name: name.into(),
39 source: PartialSource::File(path.into()),
40 }
41 }
42}
43
44#[derive(Debug)]
45pub struct ComponentContext<'a> {
46 pub web_config: &'a WebConfig,
47 pub item: Option<&'a Value>,
48 pub all_items: Option<&'a [Value]>,
49 pub popular_ids: Option<&'a [String]>,
50}
51
52impl<'a> ComponentContext<'a> {
53 #[must_use]
54 pub const fn for_page(web_config: &'a WebConfig) -> Self {
55 Self {
56 web_config,
57 item: None,
58 all_items: None,
59 popular_ids: None,
60 }
61 }
62
63 #[must_use]
64 pub const fn for_content(
65 web_config: &'a WebConfig,
66 item: &'a Value,
67 all_items: &'a [Value],
68 popular_ids: &'a [String],
69 ) -> Self {
70 Self {
71 web_config,
72 item: Some(item),
73 all_items: Some(all_items),
74 popular_ids: Some(popular_ids),
75 }
76 }
77
78 #[must_use]
79 pub const fn for_list(web_config: &'a WebConfig, all_items: &'a [Value]) -> Self {
80 Self {
81 web_config,
82 item: None,
83 all_items: Some(all_items),
84 popular_ids: None,
85 }
86 }
87}
88
89#[derive(Debug)]
90pub struct RenderedComponent {
91 pub html: String,
92 pub variable_name: String,
93}
94
95impl RenderedComponent {
96 #[must_use]
97 pub fn new(variable_name: impl Into<String>, html: impl Into<String>) -> Self {
98 Self {
99 html: html.into(),
100 variable_name: variable_name.into(),
101 }
102 }
103}
104
105#[async_trait]
109pub trait ComponentRenderer: Send + Sync {
110 fn component_id(&self) -> &'static str;
111
112 fn variable_name(&self) -> &'static str;
113
114 fn applies_to(&self) -> Vec<String> {
115 vec![]
116 }
117
118 fn partial_template(&self) -> Option<PartialTemplate> {
119 None
120 }
121
122 async fn render(&self, ctx: &ComponentContext<'_>) -> ProviderResult<RenderedComponent>;
123
124 fn priority(&self) -> u32 {
125 100
126 }
127}