From ad55323b75752ba76b21fd376a1bd52974b15300 Mon Sep 17 00:00:00 2001 From: "John T. Wodder II" Date: Wed, 10 Jul 2024 09:44:13 -0400 Subject: [PATCH 1/2] Remove a duplicate call to `get_version_endpoint()` --- src/dav/mod.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/dav/mod.rs b/src/dav/mod.rs index 732724b..7087445 100644 --- a/src/dav/mod.rs +++ b/src/dav/mod.rs @@ -167,12 +167,9 @@ impl DandiDav { &self, dandiset_id: &DandisetId, version: &VersionSpec, + endpoint: &VersionEndpoint<'_>, ) -> Result { - let md = self - .get_version_endpoint(dandiset_id, version) - .await? - .get_metadata() - .await?; + let md = endpoint.get_metadata().await?; Ok(DavItem::from(md).under_version_path(dandiset_id, version)) } @@ -214,7 +211,11 @@ impl DandiDav { dandiset_id, version, } => self - .get_dandiset_yaml(dandiset_id, version) + .get_dandiset_yaml( + dandiset_id, + version, + &self.get_version_endpoint(dandiset_id, version).await?, + ) .await .map(DavResource::Item), DavPath::DandiResource { @@ -303,7 +304,7 @@ impl DandiDav { .try_collect::>() .await?; children.push( - self.get_dandiset_yaml(dandiset_id, version) + self.get_dandiset_yaml(dandiset_id, version, &endpoint) .await .map(DavResource::Item)?, ); @@ -313,7 +314,11 @@ impl DandiDav { dandiset_id, version, } => self - .get_dandiset_yaml(dandiset_id, version) + .get_dandiset_yaml( + dandiset_id, + version, + &self.get_version_endpoint(dandiset_id, version).await?, + ) .await .map(DavResourceWithChildren::Item), DavPath::DandiResource { From e5332f7462637aa7271c89e94e3bc6645a1e9b61 Mon Sep 17 00:00:00 2001 From: "John T. Wodder II" Date: Wed, 10 Jul 2024 10:12:10 -0400 Subject: [PATCH 2/2] Encapsulate methods for working with Dandiset versions at the WebDAV level --- src/dav/mod.rs | 149 +++++++++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 66 deletions(-) diff --git a/src/dav/mod.rs b/src/dav/mod.rs index 7087445..f8c862b 100644 --- a/src/dav/mod.rs +++ b/src/dav/mod.rs @@ -12,6 +12,7 @@ use self::xml::*; use crate::consts::{DAV_XML_CONTENT_TYPE, HTML_CONTENT_TYPE}; use crate::dandi::*; use crate::paths::Component; +use crate::paths::PurePath; use crate::zarrman::*; use axum::{ body::Body, @@ -145,44 +146,29 @@ impl DandiDav { .into_response()) } - async fn get_version_endpoint( - &self, - dandiset_id: &DandisetId, - version: &VersionSpec, - ) -> Result, DavError> { + async fn get_version_handler<'a>( + &'a self, + dandiset_id: &'a DandisetId, + version_spec: &'a VersionSpec, + ) -> Result, DavError> { let d = self.dandi.dandiset(dandiset_id.clone()); - match version { - VersionSpec::Draft => Ok(d.version(VersionId::Draft)), - VersionSpec::Published(v) => Ok(d.version(VersionId::Published(v.clone()))), + let endpoint = match version_spec { + VersionSpec::Draft => d.version(VersionId::Draft), + VersionSpec::Published(v) => d.version(VersionId::Published(v.clone())), VersionSpec::Latest => match d.get().await?.most_recent_published_version { - Some(DandisetVersion { version, .. }) => Ok(d.version(version)), - None => Err(DavError::NoLatestVersion { - dandiset_id: dandiset_id.clone(), - }), + Some(DandisetVersion { version, .. }) => d.version(version), + None => { + return Err(DavError::NoLatestVersion { + dandiset_id: dandiset_id.clone(), + }) + } }, - } - } - - async fn get_dandiset_yaml( - &self, - dandiset_id: &DandisetId, - version: &VersionSpec, - endpoint: &VersionEndpoint<'_>, - ) -> Result { - let md = endpoint.get_metadata().await?; - Ok(DavItem::from(md).under_version_path(dandiset_id, version)) - } - - async fn get_dandiset_version( - &self, - dandiset_id: &DandisetId, - version: &VersionSpec, - ) -> Result<(DavCollection, VersionEndpoint<'_>), DavError> { - let endpoint = self.get_version_endpoint(dandiset_id, version).await?; - let v = endpoint.get().await?; - let path = version_path(dandiset_id, version); - let col = DavCollection::dandiset_version(v, path); - Ok((col, endpoint)) + }; + Ok(VersionHandler { + dandiset_id, + version_spec, + endpoint, + }) } async fn resolve(&self, path: &DavPath) -> Result { @@ -204,18 +190,18 @@ impl DandiDav { dandiset_id, version, } => self - .get_dandiset_version(dandiset_id, version) + .get_version_handler(dandiset_id, version) + .await? + .get() .await - .map(|(col, _)| DavResource::Collection(col)), + .map(DavResource::Collection), DavPath::DandisetYaml { dandiset_id, version, } => self - .get_dandiset_yaml( - dandiset_id, - version, - &self.get_version_endpoint(dandiset_id, version).await?, - ) + .get_version_handler(dandiset_id, version) + .await? + .get_dandiset_yaml() .await .map(DavResource::Item), DavPath::DandiResource { @@ -223,12 +209,10 @@ impl DandiDav { version, path, } => { - let res = self - .get_version_endpoint(dandiset_id, version) + self.get_version_handler(dandiset_id, version) .await? .get_resource(path) - .await?; - Ok(DavResource::from(res).under_version_path(dandiset_id, version)) + .await } DavPath::ZarrIndex => Ok(DavResource::Collection(DavCollection::zarr_index())), DavPath::ZarrPath { path } => { @@ -297,28 +281,19 @@ impl DandiDav { dandiset_id, version, } => { - let (col, endpoint) = self.get_dandiset_version(dandiset_id, version).await?; - let mut children = endpoint - .get_root_children() - .map_ok(|res| DavResource::from(res).under_version_path(dandiset_id, version)) - .try_collect::>() - .await?; - children.push( - self.get_dandiset_yaml(dandiset_id, version, &endpoint) - .await - .map(DavResource::Item)?, - ); + let handler = self.get_version_handler(dandiset_id, version).await?; + let col = handler.get().await?; + let mut children = handler.get_root_children().await?; + children.push(handler.get_dandiset_yaml().await.map(DavResource::Item)?); Ok(DavResourceWithChildren::Collection { col, children }) } DavPath::DandisetYaml { dandiset_id, version, } => self - .get_dandiset_yaml( - dandiset_id, - version, - &self.get_version_endpoint(dandiset_id, version).await?, - ) + .get_version_handler(dandiset_id, version) + .await? + .get_dandiset_yaml() .await .map(DavResourceWithChildren::Item), DavPath::DandiResource { @@ -326,12 +301,10 @@ impl DandiDav { version, path, } => { - let res = self - .get_version_endpoint(dandiset_id, version) + self.get_version_handler(dandiset_id, version) .await? .get_resource_with_children(path) - .await?; - Ok(DavResourceWithChildren::from(res).under_version_path(dandiset_id, version)) + .await } DavPath::ZarrIndex => { let col = DavCollection::zarr_index(); @@ -352,6 +325,50 @@ impl DandiDav { } } +#[derive(Clone, Debug)] +struct VersionHandler<'a> { + dandiset_id: &'a DandisetId, + version_spec: &'a VersionSpec, + endpoint: VersionEndpoint<'a>, +} + +impl VersionHandler<'_> { + async fn get(&self) -> Result { + let v = self.endpoint.get().await?; + let path = version_path(self.dandiset_id, self.version_spec); + Ok(DavCollection::dandiset_version(v, path)) + } + + async fn get_root_children(&self) -> Result, DandiError> { + self.endpoint + .get_root_children() + .map_ok(|res| { + DavResource::from(res).under_version_path(self.dandiset_id, self.version_spec) + }) + .try_collect::>() + .await + } + + async fn get_dandiset_yaml(&self) -> Result { + let md = self.endpoint.get_metadata().await?; + Ok(DavItem::from(md).under_version_path(self.dandiset_id, self.version_spec)) + } + + async fn get_resource(&self, path: &PurePath) -> Result { + let res = self.endpoint.get_resource(path).await?; + Ok(DavResource::from(res).under_version_path(self.dandiset_id, self.version_spec)) + } + + async fn get_resource_with_children( + &self, + path: &PurePath, + ) -> Result { + let res = self.endpoint.get_resource_with_children(path).await?; + Ok(DavResourceWithChildren::from(res) + .under_version_path(self.dandiset_id, self.version_spec)) + } +} + #[derive(Debug, Error)] pub(crate) enum DavError { #[error("failed to fetch data from Archive")]