Files
doctate/doctate-common/src/ack.rs
T
Brummel ed5047a3ff Add doctate-common crate for shared types
This commit introduces a new `doctate-common` crate to the workspace.
This crate will house shared data structures and constants used by both
the `doctate-server` and any future clients.

This refactoring helps to:
- Reduce code duplication.
- Improve maintainability by centralizing common logic.
- Define a clear API contract for server-client communication.

The following modules have been added:
- `ack`: Contains `AckResponse` and `AckStatus` for server responses.
- `constants`: Defines shared constants like API endpoints and multipart
  field names.
- `timestamp`: Provides utilities for handling RFC3339 timestamps,
  including conversions to and from filesystem-safe strings.
2026-04-17 15:17:37 +02:00

55 lines
1.7 KiB
Rust

use serde::{Deserialize, Serialize};
/// Server response to `POST /api/upload`. Shape is stable across all clients.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AckResponse {
pub case_id: String,
pub recorded_at: String,
pub status: AckStatus,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum AckStatus {
/// Recording accepted and persisted.
Received,
/// Case no longer exists server-side; client should delete its local copy.
Gone,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn status_serializes_lowercase() {
assert_eq!(
serde_json::to_string(&AckStatus::Received).unwrap(),
"\"received\""
);
assert_eq!(serde_json::to_string(&AckStatus::Gone).unwrap(), "\"gone\"");
}
#[test]
fn status_deserializes_lowercase() {
let got: AckStatus = serde_json::from_str("\"received\"").unwrap();
assert_eq!(got, AckStatus::Received);
let got: AckStatus = serde_json::from_str("\"gone\"").unwrap();
assert_eq!(got, AckStatus::Gone);
}
#[test]
fn response_roundtrip() {
let original = AckResponse {
case_id: "550e8400-e29b-41d4-a716-446655440000".into(),
recorded_at: "2026-04-15T10:32:00Z".into(),
status: AckStatus::Received,
};
let json = serde_json::to_string(&original).unwrap();
let decoded: AckResponse = serde_json::from_str(&json).unwrap();
assert_eq!(decoded.case_id, original.case_id);
assert_eq!(decoded.recorded_at, original.recorded_at);
assert_eq!(decoded.status, original.status);
}
}