Skip to main content

systemprompt_models/artifacts/table/
hints.rs

1//! Rendering hints for table artifacts.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use super::column::Column;
7use crate::artifacts::traits::ArtifactSchema;
8use crate::artifacts::types::SortOrder;
9use serde_json::{Value as JsonValue, json};
10
11#[derive(Debug, Clone, Default)]
12pub struct TableHints {
13    pub columns: Vec<Column>,
14    pub sortable_columns: Vec<String>,
15    pub default_sort: Option<(String, SortOrder)>,
16    pub filterable: bool,
17    pub page_size: Option<usize>,
18    pub row_click_enabled: bool,
19}
20
21impl TableHints {
22    pub fn new() -> Self {
23        Self::default()
24    }
25
26    pub fn with_columns(mut self, columns: Vec<Column>) -> Self {
27        self.columns = columns;
28        self
29    }
30
31    pub fn with_sortable(mut self, columns: Vec<String>) -> Self {
32        self.sortable_columns = columns;
33        self
34    }
35
36    pub fn with_default_sort(mut self, column: String, order: SortOrder) -> Self {
37        self.default_sort = Some((column, order));
38        self
39    }
40
41    pub const fn filterable(mut self) -> Self {
42        self.filterable = true;
43        self
44    }
45
46    pub const fn with_page_size(mut self, size: usize) -> Self {
47        self.page_size = Some(size);
48        self
49    }
50
51    pub const fn with_row_click_enabled(mut self, enabled: bool) -> Self {
52        self.row_click_enabled = enabled;
53        self
54    }
55}
56
57impl ArtifactSchema for TableHints {
58    // JSON: JSON Schema document describing the hints object for the model.
59    fn generate_schema(&self) -> JsonValue {
60        let mut hints = json!({
61            "columns": self.columns.iter().map(Column::name).collect::<Vec<_>>(),
62            "sortable_columns": self.sortable_columns,
63            "filterable": self.filterable,
64        });
65
66        if let Some((col, order)) = &self.default_sort {
67            hints["default_sort"] = json!({
68                "column": col,
69                "order": order
70            });
71        }
72
73        if let Some(size) = self.page_size {
74            hints["page_size"] = json!(size);
75        }
76
77        if self.row_click_enabled {
78            hints["row_click_enabled"] = json!(true);
79        }
80
81        let column_types: serde_json::Map<String, JsonValue> = self
82            .columns
83            .iter()
84            .map(|c| (c.name().to_owned(), json!(c.column_type())))
85            .collect();
86        hints["column_types"] = json!(column_types);
87
88        hints
89    }
90}