aster_forge_cloud_files_macos_bridge/
version.rs

1//! Exact mapping to the two-part `NSFileProviderItemVersion` contract.
2
3use aster_forge_cloud_files_core::{ContentRevision, MetadataRevision};
4
5use crate::{MacosBridgeError, Result};
6
7/// Maximum size of either `NSFileProviderItemVersion` component.
8pub const FILE_PROVIDER_ITEM_VERSION_COMPONENT_MAX_BYTES: usize = 128;
9
10const DIRECTORY_CONTENT_VERSION: &[u8] = b"aster-forge-directory-v1";
11
12/// Owned metadata/content versions for one File Provider item.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct MacosFileProviderItemVersion {
15    metadata: MetadataRevision,
16    content: ContentRevision,
17}
18
19impl MacosFileProviderItemVersion {
20    /// Creates an item version while preserving both opaque revision values exactly.
21    /// # Errors
22    ///
23    /// Returns an error when validation fails or an underlying backend, store, or platform
24    /// operation fails.
25    pub fn new(metadata: MetadataRevision, content: ContentRevision) -> Result<Self> {
26        validate_component(metadata.as_bytes(), "metadata version")?;
27        validate_component(content.as_bytes(), "content version")?;
28        Ok(Self { metadata, content })
29    }
30
31    /// Creates a directory version with a fixed content component and exact metadata revision.
32    /// # Errors
33    ///
34    /// Returns an error when validation fails or an underlying backend, store, or platform
35    /// operation fails.
36    pub fn directory(metadata: MetadataRevision) -> Result<Self> {
37        let content = ContentRevision::from_slice(DIRECTORY_CONTENT_VERSION).map_err(|_| {
38            MacosBridgeError::InvalidItemVersion {
39                reason: "directory content version could not be represented",
40            }
41        })?;
42        Self::new(metadata, content)
43    }
44
45    /// Returns the opaque metadata version bytes.
46    #[must_use]
47    pub const fn metadata(&self) -> &MetadataRevision {
48        &self.metadata
49    }
50
51    /// Returns the opaque content version bytes.
52    #[must_use]
53    pub const fn content(&self) -> &ContentRevision {
54        &self.content
55    }
56
57    /// Consumes the version into metadata and content components.
58    #[must_use]
59    pub fn into_parts(self) -> (MetadataRevision, ContentRevision) {
60        (self.metadata, self.content)
61    }
62}
63
64fn validate_component(value: &[u8], _field: &'static str) -> Result<()> {
65    if value.len() > FILE_PROVIDER_ITEM_VERSION_COMPONENT_MAX_BYTES {
66        return Err(MacosBridgeError::InvalidItemVersion {
67            reason: "item version component exceeds the File Provider 128-byte limit",
68        });
69    }
70    Ok(())
71}