aster_forge_cloud_files_linux/
remote.rs

1//! Product-neutral acceptance values for durable remote namespace changes.
2
3use aster_forge_cloud_files_core::{CloudItem, CloudItemKey};
4
5use crate::{LinuxInode, LinuxInodeRecord, LinuxNodeKind, Result, validate_linux_name};
6
7/// One durable remote item and its product-allocated stable Linux mapping.
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct LinuxRemoteEntry {
10    item: CloudItem,
11    inode_record: LinuxInodeRecord,
12}
13
14impl LinuxRemoteEntry {
15    #[must_use]
16    pub const fn new(item: CloudItem, inode_record: LinuxInodeRecord) -> Self {
17        Self { item, inode_record }
18    }
19
20    #[must_use]
21    pub const fn item(&self) -> &CloudItem {
22        &self.item
23    }
24
25    #[must_use]
26    pub const fn inode_record(&self) -> &LinuxInodeRecord {
27        &self.inode_record
28    }
29
30    #[must_use]
31    pub fn into_parts(self) -> (CloudItem, LinuxInodeRecord) {
32        (self.item, self.inode_record)
33    }
34}
35
36/// Last durable directory location of an upserted stable item.
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct LinuxRemoteLocation {
39    parent_key: CloudItemKey,
40    name: String,
41}
42
43impl LinuxRemoteLocation {
44    /// # Errors
45    ///
46    /// Returns an error when validation fails or an underlying backend, store, or platform
47    /// operation fails.
48    pub fn new(parent_key: CloudItemKey, name: impl Into<String>) -> Result<Self> {
49        let name = name.into();
50        validate_linux_name(&name)?;
51        Ok(Self { parent_key, name })
52    }
53
54    #[must_use]
55    pub const fn parent_key(&self) -> &CloudItemKey {
56        &self.parent_key
57    }
58
59    #[must_use]
60    pub fn name(&self) -> &str {
61        &self.name
62    }
63}
64
65/// Exact durable facts for one remote deletion or destination replacement.
66#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct LinuxRemoteDelete {
68    key: CloudItemKey,
69    inode_record: LinuxInodeRecord,
70    parent_key: CloudItemKey,
71    name: String,
72    kind: LinuxNodeKind,
73}
74
75impl LinuxRemoteDelete {
76    /// # Errors
77    ///
78    /// Returns an error when validation fails or an underlying backend, store, or platform
79    /// operation fails.
80    pub fn new(
81        key: CloudItemKey,
82        inode_record: LinuxInodeRecord,
83        parent_key: CloudItemKey,
84        name: impl Into<String>,
85        kind: LinuxNodeKind,
86    ) -> Result<Self> {
87        let name = name.into();
88        validate_linux_name(&name)?;
89        Ok(Self {
90            key,
91            inode_record,
92            parent_key,
93            name,
94            kind,
95        })
96    }
97
98    #[must_use]
99    pub const fn key(&self) -> &CloudItemKey {
100        &self.key
101    }
102
103    #[must_use]
104    pub const fn inode_record(&self) -> &LinuxInodeRecord {
105        &self.inode_record
106    }
107
108    #[must_use]
109    pub const fn parent_key(&self) -> &CloudItemKey {
110        &self.parent_key
111    }
112
113    #[must_use]
114    pub fn name(&self) -> &str {
115        &self.name
116    }
117
118    #[must_use]
119    pub const fn kind(&self) -> LinuxNodeKind {
120        self.kind
121    }
122}
123
124/// Durable product transaction result for one remote create, metadata update, or move.
125#[derive(Debug, Clone, PartialEq, Eq)]
126pub struct LinuxRemoteUpsert {
127    entry: LinuxRemoteEntry,
128    previous: Option<LinuxRemoteLocation>,
129    replaced: Option<LinuxRemoteDelete>,
130}
131
132impl LinuxRemoteUpsert {
133    #[must_use]
134    pub const fn new(
135        entry: LinuxRemoteEntry,
136        previous: Option<LinuxRemoteLocation>,
137        replaced: Option<LinuxRemoteDelete>,
138    ) -> Self {
139        Self {
140            entry,
141            previous,
142            replaced,
143        }
144    }
145
146    #[must_use]
147    pub const fn entry(&self) -> &LinuxRemoteEntry {
148        &self.entry
149    }
150
151    #[must_use]
152    pub const fn previous(&self) -> Option<&LinuxRemoteLocation> {
153        self.previous.as_ref()
154    }
155
156    #[must_use]
157    pub const fn replaced(&self) -> Option<&LinuxRemoteDelete> {
158        self.replaced.as_ref()
159    }
160
161    #[must_use]
162    pub fn into_parts(
163        self,
164    ) -> (
165        LinuxRemoteEntry,
166        Option<LinuxRemoteLocation>,
167        Option<LinuxRemoteDelete>,
168    ) {
169        (self.entry, self.previous, self.replaced)
170    }
171}
172
173/// One product-persisted remote namespace transition ready for engine exposure.
174#[derive(Debug, Clone, PartialEq, Eq)]
175#[expect(
176    clippy::large_enum_variant,
177    reason = "remote changes are low-frequency control values and should not require heap allocation"
178)]
179pub enum LinuxRemoteChange {
180    Upsert(LinuxRemoteUpsert),
181    Delete(LinuxRemoteDelete),
182}
183
184/// One native kernel-cache notification produced after an engine transition.
185#[derive(Debug, Clone, PartialEq, Eq)]
186pub enum LinuxInvalidation {
187    Entry {
188        parent: LinuxInode,
189        name: String,
190    },
191    Inode {
192        inode: LinuxInode,
193    },
194    Delete {
195        parent: LinuxInode,
196        child: LinuxInode,
197        name: String,
198    },
199}