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