Split the server into three crates (#56)

This will make it easier to build variations on the server, or embed it
into larger projects.
This commit is contained in:
Dustin J. Mitchell 2024-11-17 15:12:42 -05:00 committed by GitHub
parent 5769781553
commit 47ce4c1e3b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 1243 additions and 57 deletions

59
server/src/api/mod.rs Normal file
View file

@ -0,0 +1,59 @@
use actix_web::{error, http::StatusCode, web, HttpRequest, Result, Scope};
use taskchampion_sync_server_core::{ClientId, ServerConfig, Storage};
mod add_snapshot;
mod add_version;
mod get_child_version;
mod get_snapshot;
/// The content-type for history segments (opaque blobs of bytes)
pub(crate) const HISTORY_SEGMENT_CONTENT_TYPE: &str =
"application/vnd.taskchampion.history-segment";
/// The content-type for snapshots (opaque blobs of bytes)
pub(crate) const SNAPSHOT_CONTENT_TYPE: &str = "application/vnd.taskchampion.snapshot";
/// The header name for version ID
pub(crate) const VERSION_ID_HEADER: &str = "X-Version-Id";
/// The header name for client id
pub(crate) const CLIENT_ID_HEADER: &str = "X-Client-Id";
/// The header name for parent version ID
pub(crate) const PARENT_VERSION_ID_HEADER: &str = "X-Parent-Version-Id";
/// The header name for parent version ID
pub(crate) const SNAPSHOT_REQUEST_HEADER: &str = "X-Snapshot-Request";
/// The type containing a reference to the persistent state for the server
pub(crate) struct ServerState {
pub(crate) storage: Box<dyn Storage>,
pub(crate) config: ServerConfig,
}
pub(crate) fn api_scope() -> Scope {
web::scope("")
.service(get_child_version::service)
.service(add_version::service)
.service(get_snapshot::service)
.service(add_snapshot::service)
}
/// Convert a failure::Error to an Actix ISE
fn failure_to_ise(err: anyhow::Error) -> impl actix_web::ResponseError {
error::InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR)
}
/// Get the client id
fn client_id_header(req: &HttpRequest) -> Result<ClientId> {
fn badrequest() -> error::Error {
error::ErrorBadRequest("bad x-client-id")
}
if let Some(client_id_hdr) = req.headers().get(CLIENT_ID_HEADER) {
let client_id = client_id_hdr.to_str().map_err(|_| badrequest())?;
let client_id = ClientId::parse_str(client_id).map_err(|_| badrequest())?;
Ok(client_id)
} else {
Err(badrequest())
}
}