Skip to content

Commit

Permalink
Encapsulate methods for working with Dandiset versions at the WebDAV …
Browse files Browse the repository at this point in the history
…level
  • Loading branch information
jwodder committed Jul 10, 2024
1 parent ad55323 commit e5332f7
Showing 1 changed file with 83 additions and 66 deletions.
149 changes: 83 additions & 66 deletions src/dav/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -145,44 +146,29 @@ impl DandiDav {
.into_response())
}

async fn get_version_endpoint(
&self,
dandiset_id: &DandisetId,
version: &VersionSpec,
) -> Result<VersionEndpoint<'_>, DavError> {
async fn get_version_handler<'a>(
&'a self,
dandiset_id: &'a DandisetId,
version_spec: &'a VersionSpec,
) -> Result<VersionHandler<'a>, DavError> {

Check warning on line 153 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L149-L153

Added lines #L149 - L153 were not covered by tests
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())),

Check warning on line 157 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L155-L157

Added lines #L155 - L157 were not covered by tests
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),

Check warning on line 159 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L159

Added line #L159 was not covered by tests
None => {
return Err(DavError::NoLatestVersion {
dandiset_id: dandiset_id.clone(),
})

Check warning on line 163 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L161-L163

Added lines #L161 - L163 were not covered by tests
}
},
}
}

async fn get_dandiset_yaml(
&self,
dandiset_id: &DandisetId,
version: &VersionSpec,
endpoint: &VersionEndpoint<'_>,
) -> Result<DavItem, DavError> {
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,
})

Check warning on line 171 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L167-L171

Added lines #L167 - L171 were not covered by tests
}

async fn resolve(&self, path: &DavPath) -> Result<DavResource, DavError> {
Expand All @@ -204,31 +190,29 @@ impl DandiDav {
dandiset_id,
version,
} => self
.get_dandiset_version(dandiset_id, version)
.get_version_handler(dandiset_id, version)
.await?
.get()

Check warning on line 195 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L193-L195

Added lines #L193 - L195 were not covered by tests
.await
.map(|(col, _)| DavResource::Collection(col)),
.map(DavResource::Collection),

Check warning on line 197 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L197

Added line #L197 was not covered by tests
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()

Check warning on line 204 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L202-L204

Added lines #L202 - L204 were not covered by tests
.await
.map(DavResource::Item),
DavPath::DandiResource {
dandiset_id,
version,
path,
} => {
let res = self
.get_version_endpoint(dandiset_id, version)
self.get_version_handler(dandiset_id, version)

Check warning on line 212 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L212

Added line #L212 was not covered by tests
.await?
.get_resource(path)
.await?;
Ok(DavResource::from(res).under_version_path(dandiset_id, version))
.await

Check warning on line 215 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L215

Added line #L215 was not covered by tests
}
DavPath::ZarrIndex => Ok(DavResource::Collection(DavCollection::zarr_index())),
DavPath::ZarrPath { path } => {
Expand Down Expand Up @@ -297,41 +281,30 @@ 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::<Vec<_>>()
.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)?);

Check warning on line 287 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L284-L287

Added lines #L284 - L287 were not covered by tests
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()

Check warning on line 296 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L294-L296

Added lines #L294 - L296 were not covered by tests
.await
.map(DavResourceWithChildren::Item),
DavPath::DandiResource {
dandiset_id,
version,
path,
} => {
let res = self
.get_version_endpoint(dandiset_id, version)
self.get_version_handler(dandiset_id, version)

Check warning on line 304 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L304

Added line #L304 was not covered by tests
.await?
.get_resource_with_children(path)
.await?;
Ok(DavResourceWithChildren::from(res).under_version_path(dandiset_id, version))
.await

Check warning on line 307 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L307

Added line #L307 was not covered by tests
}
DavPath::ZarrIndex => {
let col = DavCollection::zarr_index();
Expand All @@ -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<DavCollection, DavError> {
let v = self.endpoint.get().await?;
let path = version_path(self.dandiset_id, self.version_spec);
Ok(DavCollection::dandiset_version(v, path))
}

Check warning on line 340 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L336-L340

Added lines #L336 - L340 were not covered by tests

async fn get_root_children(&self) -> Result<Vec<DavResource>, DandiError> {
self.endpoint
.get_root_children()
.map_ok(|res| {
DavResource::from(res).under_version_path(self.dandiset_id, self.version_spec)
})
.try_collect::<Vec<_>>()
.await
}

Check warning on line 350 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L342-L350

Added lines #L342 - L350 were not covered by tests

async fn get_dandiset_yaml(&self) -> Result<DavItem, DavError> {
let md = self.endpoint.get_metadata().await?;
Ok(DavItem::from(md).under_version_path(self.dandiset_id, self.version_spec))
}

Check warning on line 355 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L352-L355

Added lines #L352 - L355 were not covered by tests

async fn get_resource(&self, path: &PurePath) -> Result<DavResource, DavError> {
let res = self.endpoint.get_resource(path).await?;
Ok(DavResource::from(res).under_version_path(self.dandiset_id, self.version_spec))
}

Check warning on line 360 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L357-L360

Added lines #L357 - L360 were not covered by tests

async fn get_resource_with_children(
&self,
path: &PurePath,
) -> Result<DavResourceWithChildren, DavError> {
let res = self.endpoint.get_resource_with_children(path).await?;
Ok(DavResourceWithChildren::from(res)
.under_version_path(self.dandiset_id, self.version_spec))
}

Check warning on line 369 in src/dav/mod.rs

View check run for this annotation

Codecov / codecov/patch

src/dav/mod.rs#L362-L369

Added lines #L362 - L369 were not covered by tests
}

#[derive(Debug, Error)]
pub(crate) enum DavError {
#[error("failed to fetch data from Archive")]
Expand Down

0 comments on commit e5332f7

Please sign in to comment.