reinhardt_admin/server/
export.rs1use crate::adapters::{AdminDatabase, AdminRecord, AdminSite, ExportFormat, ExportResponse};
6use reinhardt_pages::server_fn::{ServerFnError, server_fn};
7use std::sync::Arc;
8
9#[cfg(not(target_arch = "wasm32"))]
10use super::error::MapServerFnError;
11
12#[server_fn(use_inject = true)]
33pub async fn export_data(
34 model_name: String,
35 format: ExportFormat,
36 #[inject] site: Arc<AdminSite>,
37 #[inject] db: Arc<AdminDatabase>,
38) -> Result<ExportResponse, ServerFnError> {
39 let model_admin = site.get_model_admin(&model_name).map_server_fn_error()?;
40 let table_name = model_admin.table_name();
41
42 let results = db
44 .list::<AdminRecord>(table_name, vec![], 0, u64::MAX)
45 .await
46 .map_server_fn_error()?;
47
48 let (data, filename, content_type) = match format {
50 ExportFormat::JSON => {
51 let json = serde_json::to_vec_pretty(&results).map_err(|e| {
52 ServerFnError::serialization(format!("JSON serialization failed: {}", e))
53 })?;
54 (
55 json,
56 format!("{}.json", model_name.to_lowercase()),
57 "application/json",
58 )
59 }
60 ExportFormat::CSV => {
61 let mut wtr = csv::Writer::from_writer(vec![]);
62
63 for record in results {
65 wtr.serialize(record).map_err(|e| {
66 ServerFnError::serialization(format!("CSV serialization failed: {}", e))
67 })?;
68 }
69
70 let data = wtr
71 .into_inner()
72 .map_err(|e| ServerFnError::serialization(format!("CSV write failed: {}", e)))?;
73
74 (
75 data,
76 format!("{}.csv", model_name.to_lowercase()),
77 "text/csv",
78 )
79 }
80 ExportFormat::TSV => {
81 let mut wtr = csv::WriterBuilder::new()
82 .delimiter(b'\t')
83 .from_writer(vec![]);
84
85 for record in results {
87 wtr.serialize(record).map_err(|e| {
88 ServerFnError::serialization(format!("TSV serialization failed: {}", e))
89 })?;
90 }
91
92 let data = wtr
93 .into_inner()
94 .map_err(|e| ServerFnError::serialization(format!("TSV write failed: {}", e)))?;
95
96 (
97 data,
98 format!("{}.tsv", model_name.to_lowercase()),
99 "text/tab-separated-values",
100 )
101 }
102 ExportFormat::Excel => {
103 unimplemented!("Excel export is not yet implemented")
104 }
105 ExportFormat::XML => {
106 unimplemented!("XML export is not yet implemented")
107 }
108 };
109
110 Ok(ExportResponse {
111 data,
112 filename,
113 content_type: content_type.to_string(),
114 })
115}