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