diff --git a/crates/proton-drive-rs/src/client.rs b/crates/proton-drive-rs/src/client.rs index 6bed35c..2ee6719 100644 --- a/crates/proton-drive-rs/src/client.rs +++ b/crates/proton-drive-rs/src/client.rs @@ -470,6 +470,7 @@ impl ProtonDriveClient { let link = detail.link; let file = detail .file + .or(detail.photo) .ok_or_else(|| ProtonError::invalid_operation(format!("node {uid} is not a file")))?; let content_key_packet_b64 = file.content_key_packet.ok_or_else(|| { @@ -559,6 +560,7 @@ impl ProtonDriveClient { let link = detail.link; let file = detail .file + .or(detail.photo) .ok_or_else(|| ProtonError::invalid_operation(format!("node {uid} is not a file")))?; let content_key_packet_b64 = file.content_key_packet.ok_or_else(|| { @@ -896,6 +898,7 @@ impl ProtonDriveClient { let link = detail.link; let file = detail .file + .or(detail.photo) .ok_or_else(|| ProtonError::invalid_operation(format!("node {uid} is not a file")))?; let content_key_packet_b64 = file.content_key_packet.ok_or_else(|| { @@ -2322,6 +2325,7 @@ impl ProtonDriveClient { let link = detail.link; let file = detail .file + .or(detail.photo) .ok_or_else(|| ProtonError::invalid_operation(format!("node {uid} is not a file")))?; let content_key_packet_b64 = file.content_key_packet.ok_or_else(|| { @@ -2532,7 +2536,7 @@ impl ProtonDriveClient { NodeKind::Folder } LinkType::File => { - let file = details.file.as_ref().ok_or_else(|| { + let file = details.file_properties().ok_or_else(|| { ProtonError::invalid_operation("file node missing file properties") })?; diff --git a/crates/proton-drive-rs/src/dtos.rs b/crates/proton-drive-rs/src/dtos.rs index 12510e8..0399f9b 100644 --- a/crates/proton-drive-rs/src/dtos.rs +++ b/crates/proton-drive-rs/src/dtos.rs @@ -100,6 +100,19 @@ pub struct LinkDetailsDto { pub folder: Option, #[serde(rename = "File")] pub file: Option, + /// Photos-volume `/links` returns file properties under `Photo` (a superset + /// of `File`) rather than `File`. Deserialized as [`FileDto`]; the extra + /// photo fields are ignored. C# `linkDetailsDto.File ?? linkDetailsDto.Photo`. + #[serde(rename = "Photo")] + pub photo: Option, +} + +impl LinkDetailsDto { + /// File properties for a file/photo node, preferring `File` and falling back + /// to the photos-volume `Photo` block. + pub fn file_properties(&self) -> Option<&FileDto> { + self.file.as_ref().or(self.photo.as_ref()) + } } #[derive(Debug, Deserialize)]