diff options
Diffstat (limited to 'src/handlers.rs')
| -rw-r--r-- | src/handlers.rs | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/handlers.rs b/src/handlers.rs index 5d31600..7067f3a 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -21,6 +21,40 @@ pub async fn list_measurements( State(pool): State<PgPool>, AppQuery(query): AppQuery<ListQuery>, ) -> Result<Json<Vec<MeasurementView>>, AppError> { + Ok(Json(fetch_measurements(&pool, &query).await?)) +} + +pub async fn export_measurements( + State(pool): State<PgPool>, + AppQuery(query): AppQuery<ListQuery>, +) -> Result<([(HeaderName, &'static str); 2], Vec<u8>), AppError> { + let rows = fetch_measurements(&pool, &query).await?; + let mut writer = csv::WriterBuilder::new() + .has_headers(false) + .from_writer(Vec::new()); + writer.write_record(["id", "measured_at", "metric_type", "value", "unit"])?; + for row in &rows { + writer.serialize(row)?; + } + let csv = writer + .into_inner() + .map_err(|e| csv::Error::from(e.into_error()))?; + Ok(( + [ + (header::CONTENT_TYPE, "text/csv; charset=utf-8"), + ( + header::CONTENT_DISPOSITION, + "attachment; filename=\"measurements.csv\"", + ), + ], + csv, + )) +} + +async fn fetch_measurements( + pool: &PgPool, + query: &ListQuery, +) -> Result<Vec<MeasurementView>, AppError> { let limit = match query.limit { Some(x) if (x > 0) => Some(x), None => None, @@ -52,9 +86,9 @@ pub async fn list_measurements( matches!(query.order, Order::Desc), query.metric_type ) - .fetch_all(&pool) + .fetch_all(pool) .await?; - Ok(Json(rows)) + Ok(rows) } pub async fn create_measurement( |
