Skip to main content

twine_core/application/
files.rs

1use std::path::{Path, PathBuf};
2
3use super::{Application, ApplicationError};
4use crate::files::{FileError, FileSaveOutcome, FileSaveRequest, FileSnapshot};
5
6impl Application {
7    /// Saves a bounded text edit, returning a conflict without writing when the disk version differs.
8    /// Contents never enter the event journal. Call on a worker, as this performs disk I/O.
9    ///
10    /// # Errors
11    /// Returns an error for a stale folder, invalid/unsupported paths, oversized text, or failed I/O.
12    pub fn save_file(
13        &self,
14        request: &FileSaveRequest,
15    ) -> Result<FileSaveOutcome, ApplicationError> {
16        let _commands = self
17            .commands
18            .lock()
19            .map_err(|_| ApplicationError::Poisoned)?;
20        if self.lock_inner()?.folders.state().open_folder.as_deref()
21            != Some(request.folder.as_path())
22        {
23            return Err(FileError::FolderChanged.into());
24        }
25        let result = crate::files::save(request);
26        // Drop snapshots and in-flight scans from before this save/conflict check.
27        self.files.clear();
28        Ok(result?)
29    }
30
31    /// Watches only the visible directories and selected file on a dedicated worker. Returns no
32    /// snapshot until the first scan completes or while the revision is unchanged. File contents
33    /// stay out of the event journal, which would retain old versions. Poll at 500 ms intervals.
34    ///
35    /// # Errors
36    /// Returns an error for a stale folder, invalid paths, or poisoned state locks.
37    pub fn poll_files(
38        &self,
39        folder: &Path,
40        directories: &[PathBuf],
41        file: Option<&Path>,
42        revision: Option<u64>,
43    ) -> Result<Option<FileSnapshot>, ApplicationError> {
44        let _commands = self
45            .commands
46            .lock()
47            .map_err(|_| ApplicationError::Poisoned)?;
48        if self.lock_inner()?.folders.state().open_folder.as_deref() != Some(folder) {
49            return Err(FileError::FolderChanged.into());
50        }
51        Ok(self.files.poll(folder, directories, file, revision)?)
52    }
53}