diff --git a/Cargo.lock b/Cargo.lock index a6f4141..933ead9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -586,9 +586,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.6" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c376d08ea6aa96aafe61237c7200d1241cb177b7d3a542d791f2d118e9cbb955" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ "darling_core", "darling_macro", @@ -596,9 +596,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.6" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33043dcd19068b8192064c704b3f83eb464f91f1ff527b44a4e2b08d9cdb8855" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", @@ -610,9 +610,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.6" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", @@ -816,6 +816,7 @@ dependencies = [ "actix-utils", "actix-web", "bytes", + "derive_more", "dicom", "dicom-json", "dicom-object", @@ -1886,9 +1887,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", diff --git a/examples/simple_server/src/main.rs b/examples/simple_server/src/main.rs index 1976f85..df8fdce 100644 --- a/examples/simple_server/src/main.rs +++ b/examples/simple_server/src/main.rs @@ -7,7 +7,7 @@ use dicom::{ }; use dicom_object::FileDicomObject; use dicomweb_server::{ - dicomweb_config, study_filter, QidoInstanceQuery, QidoSeriesQuery, QidoStudyQuery, + actix::dicomweb_config, study_filter, QidoInstanceQuery, QidoSeriesQuery, QidoStudyQuery, INSTANCE_TAGS, SERIES_TAGS, STUDY_TAGS, }; use itertools::Itertools; diff --git a/server/Cargo.toml b/server/Cargo.toml index da21856..c6aa878 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -5,11 +5,16 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = ["actix"] +actix = ["dep:actix-web", "dep:actix-multipart", "dep:actix-utils"] + [dependencies] -actix-multipart = "0.6.1" -actix-utils = "3.0.1" -actix-web = "4.5.1" +actix-multipart = { version = "0.6.1", optional = true } +actix-utils = { version = "3.0.1", optional = true } +actix-web = { version = "4.5.1", optional = true } bytes = "1.5.0" +derive_more = "0.99.17" dicom = "0.6.3" dicom-json = "0.1.1" dicom-object = "0.6.3" diff --git a/server/src/multipart/extractor.rs b/server/src/actix/extractor.rs similarity index 93% rename from server/src/multipart/extractor.rs rename to server/src/actix/extractor.rs index 5295186..1bba0c3 100644 --- a/server/src/multipart/extractor.rs +++ b/server/src/actix/extractor.rs @@ -3,7 +3,7 @@ use actix_utils::future::{ready, Ready}; use actix_web::{dev::Payload, Error, FromRequest, HttpRequest}; -use crate::multipart::MultipartReader; +use super::MultipartReader; impl FromRequest for MultipartReader { type Error = Error; diff --git a/server/src/actix/mod.rs b/server/src/actix/mod.rs new file mode 100644 index 0000000..f6c0021 --- /dev/null +++ b/server/src/actix/mod.rs @@ -0,0 +1,28 @@ +mod extractor; +mod multipart; +mod qido; +mod stow; +mod wado; + +use multipart::*; +use qido::*; +use stow::*; +use wado::*; + +pub use qido::qido_config; +pub use stow::stow_config; +pub use wado::wado_config; + +pub fn dicomweb_config(cfg: &mut actix_web::web::ServiceConfig) { + cfg.service(store_instances) + .service(store_instances_for_study) + .service(search_studies_all) + .service(search_series_all) + .service(search_series_study_level) + .service(search_instances_all) + .service(search_instances_study_level) + .service(search_instances_series_level) + .service(retrieve_instance) + .service(retrieve_series) + .service(retrieve_study); +} diff --git a/server/src/actix/multipart/mod.rs b/server/src/actix/multipart/mod.rs new file mode 100644 index 0000000..b06963d --- /dev/null +++ b/server/src/actix/multipart/mod.rs @@ -0,0 +1,5 @@ +mod reader; +mod writer; + +pub use reader::*; +pub use writer::*; diff --git a/server/src/multipart/reader.rs b/server/src/actix/multipart/reader.rs similarity index 100% rename from server/src/multipart/reader.rs rename to server/src/actix/multipart/reader.rs diff --git a/server/src/multipart/builder.rs b/server/src/actix/multipart/writer.rs similarity index 100% rename from server/src/multipart/builder.rs rename to server/src/actix/multipart/writer.rs diff --git a/server/src/qido.rs b/server/src/actix/qido.rs similarity index 84% rename from server/src/qido.rs rename to server/src/actix/qido.rs index 8ef8c59..df489a2 100644 --- a/server/src/qido.rs +++ b/server/src/actix/qido.rs @@ -1,24 +1,8 @@ use actix_web::{get, web, HttpResponse, Responder}; use dicom_json::DicomJson; -use dicom_object::{InMemDicomObject, Tag}; -use serde::Deserialize; - -use crate::DicomWebServer; - -/// QIDO-RS -/// -/// See https://www.dicomstandard.org/using/dicomweb/query-qido-rs for more information -/// More detail can be found in PS3.18 10.6. -#[derive(Deserialize, Debug)] -pub struct QidoStudyQuery { - pub limit: Option, - pub offset: Option, - pub fuzzymatching: Option, - #[serde(skip_deserializing)] - pub includefields: Vec, - #[serde(skip_deserializing)] - pub matches: Vec<(Tag, String)>, -} +use dicom_object::InMemDicomObject; + +use crate::{DicomWebServer, QidoInstanceQuery, QidoSeriesQuery, QidoStudyQuery}; #[get("/studies")] pub async fn search_studies_all( @@ -45,16 +29,6 @@ pub async fn search_studies_all( } } -#[derive(Deserialize, Debug)] -pub struct QidoSeriesQuery { - limit: Option, - offset: Option, - includefield: Option, - modality: Option, - series_instance_uid: Option, - series_description: Option, -} - #[get("/studies/{study_uid}/series")] pub async fn search_series_study_level( callbacks: web::Data, @@ -132,15 +106,6 @@ pub async fn search_series_all( } } -#[derive(Deserialize, Debug)] -pub struct QidoInstanceQuery { - limit: Option, - offset: Option, - includefield: Option, - sop_instance_uid: Option, - instance_number: Option, -} - #[get("/studies/{study_uid}/series/{series_uid}/instances")] pub async fn search_instances_series_level( callbacks: web::Data, diff --git a/server/src/stow.rs b/server/src/actix/stow.rs similarity index 98% rename from server/src/stow.rs rename to server/src/actix/stow.rs index 9363425..f618cad 100644 --- a/server/src/stow.rs +++ b/server/src/actix/stow.rs @@ -8,7 +8,9 @@ use dicom_json::DicomJson; use dicom_object::{FileDicomObject, InMemDicomObject}; use futures_util::StreamExt; -use crate::{multipart::MultipartReader, DicomWebServer}; +use crate::DicomWebServer; + +use super::MultipartReader; async fn collect_dicom_files( request: HttpRequest, diff --git a/server/src/wado.rs b/server/src/actix/wado.rs similarity index 98% rename from server/src/wado.rs rename to server/src/actix/wado.rs index 52a8d9f..2ff5b94 100644 --- a/server/src/wado.rs +++ b/server/src/actix/wado.rs @@ -2,7 +2,7 @@ use std::io::Write; use actix_web::{get, web, HttpResponse, Responder}; -use crate::{multipart::MultipartWriter, DicomWebServer}; +use crate::{actix::MultipartWriter, DicomWebServer}; /// WADO-RS /// diff --git a/server/src/lib.rs b/server/src/lib.rs index ee904af..6ad7c86 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,20 +1,48 @@ use dicom::{dictionary_std::tags, object::InMemDicomObject}; +use serde::Deserialize; mod filter; -mod multipart; -mod qido; -mod stow; -mod wado; use dicom_object::{FileDicomObject, Tag}; -use qido::*; -use stow::*; -use wado::*; pub use filter::study_filter; -pub use qido::{qido_config, QidoInstanceQuery, QidoSeriesQuery, QidoStudyQuery}; -pub use stow::stow_config; -pub use wado::wado_config; + +#[cfg(feature = "actix")] +pub mod actix; + +/// QIDO-RS +/// +/// See https://www.dicomstandard.org/using/dicomweb/query-qido-rs for more information +/// More detail can be found in PS3.18 10.6. +#[derive(Deserialize, Debug)] +pub struct QidoStudyQuery { + pub limit: Option, + pub offset: Option, + pub fuzzymatching: Option, + #[serde(skip_deserializing)] + pub includefields: Vec, + #[serde(skip_deserializing)] + pub matches: Vec<(Tag, String)>, +} + +#[derive(Deserialize, Debug)] +pub struct QidoSeriesQuery { + limit: Option, + offset: Option, + includefield: Option, + modality: Option, + series_instance_uid: Option, + series_description: Option, +} + +#[derive(Deserialize, Debug)] +pub struct QidoInstanceQuery { + limit: Option, + offset: Option, + includefield: Option, + sop_instance_uid: Option, + instance_number: Option, +} /// DICOMWeb Server /// Provide the callbacks for the QIDO-RS and WADO-RS endpoints. @@ -76,17 +104,3 @@ pub const INSTANCE_TAGS: [Tag; 3] = [ tags::SOP_INSTANCE_UID, tags::INSTANCE_NUMBER, ]; - -pub fn dicomweb_config(cfg: &mut actix_web::web::ServiceConfig) { - cfg.service(store_instances) - .service(store_instances_for_study) - .service(search_studies_all) - .service(search_series_all) - .service(search_series_study_level) - .service(search_instances_all) - .service(search_instances_study_level) - .service(search_instances_series_level) - .service(retrieve_instance) - .service(retrieve_series) - .service(retrieve_study); -} diff --git a/server/src/multipart/mod.rs b/server/src/multipart/mod.rs deleted file mode 100644 index 2f8b310..0000000 --- a/server/src/multipart/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod builder; -mod extractor; -mod reader; - -pub use builder::*; -pub use reader::*;