| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- use std::ffi::{OsStr, OsString};
- use std::fs;
- use std::path::Path;
- use std::sync::Arc;
-
- use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
- use tokio::sync::Mutex;
-
- use super::{Database, Error};
-
- pub struct FileTree {
- db: Arc<Mutex<Database>>,
- new_version_notifiers: Vec<UnboundedSender<NewVersionEvent>>,
- next_version_source: u64,
- root_path: OsString,
- }
-
- impl FileTree {
- pub fn open(db: Arc<Mutex<Database>>, directory: &OsStr) -> Result<FileTree, Error> {
- // Check whether the database entry for this file tree exists and fetch the root
- // file ID.
- // TODO
-
- // Create a lock file to make sure that the directory is only synchronized once.
- // TODO
-
- // Clear up any temporary files which were left over.
- // TODO
-
- // Enqueue the root directory to be rechecked against the database.
- // TODO
-
- Ok(FileTree {
- db,
- new_version_notifiers: Vec::new(),
- next_version_source: 0,
- root_path: directory.to_owned(),
- })
- }
-
- pub fn root_path(&self) -> &OsStr {
- &self.root_path
- }
-
- pub fn new_notifier(&mut self) -> NewVersionNotifier {
- let (send, receive) = unbounded_channel();
- self.new_version_notifiers.push(send);
- NewVersionNotifier { receive }
- }
-
- pub fn new_version_source(&mut self) -> NewVersionSource {
- let source = NewVersionSource {
- id: self.next_version_source,
- };
- self.next_version_source += 1;
- source
- }
-
- // TODO: Limit on size of all temporary files, make this function return a
- // future which yields a temporary file once enough space is available?
- pub fn create_temporary_file(&self, _target_path: &OsStr) -> Result<TemporaryFile, Error> {
- // TODO
- panic!("Not yet implemented.");
- }
-
- pub async fn lock_path<P>(&mut self, path: P) -> Option<LockedPath>
- where
- P: AsRef<Path>,
- {
- let _path = path.as_ref();
- // TODO
- panic!("Not yet implemented.");
- }
-
- pub async fn lock_two_paths<P1, P2>(&mut self, path1: P1, path2: P2) -> Option<LockedPath>
- where
- P1: AsRef<Path>,
- P2: AsRef<Path>,
- {
- let _path1 = path1.as_ref();
- let _path2 = path2.as_ref();
- // TODO
- panic!("Not yet implemented.");
- }
- }
-
- pub struct LockedPath {
- // TODO
- }
-
- impl LockedPath {
- pub fn get_file_info<P>(&self, path: P) -> Option<FileInfo>
- where
- P: AsRef<Path>,
- {
- let _path = path.as_ref();
- // TODO
- panic!("Not yet implemented.");
- }
-
- pub fn get_directory_listing(&self, _path: &OsStr) -> Option<Vec<FileInfo>> {
- // TODO
- panic!("Not yet implemented.");
- }
-
- pub fn local_file_changed(&self, _source: NewVersionSource, _path: &OsStr, _info: FileInfo) {
- // TODO
- panic!("Not yet implemented.");
- }
-
- pub fn local_file_removed<P>(&self, _source: NewVersionSource, _path: P)
- where
- P: AsRef<Path>,
- {
- // TODO
- panic!("Not yet implemented.");
- }
-
- pub fn update_file(
- &self,
- _source: NewVersionSource,
- _path: &OsStr,
- _info: FileInfo,
- _contents: TemporaryFile,
- _origin: OriginInfo,
- ) -> Result<NewVersionEvent, Error> {
- // TODO
- panic!("Not yet implemented.");
- }
-
- pub fn create_directory<P>(
- &self,
- _source: NewVersionSource,
- _path: P,
- _origin: OriginInfo,
- ) -> Result<NewVersionEvent, Error>
- where
- P: AsRef<Path>,
- {
- // TODO
- panic!("Not yet implemented.");
- }
- }
-
- impl Drop for LockedPath {
- fn drop(&mut self) {
- // Release the lock again.
- // TODO
- }
- }
-
- pub struct NewVersionNotifier {
- // TODO: Probably should not be public.
- pub receive: UnboundedReceiver<NewVersionEvent>,
- }
-
- pub struct NewVersionEvent {
- pub source: NewVersionSource,
- // TODO
- }
-
- #[derive(Clone, Copy, PartialEq, Eq)]
- pub struct NewVersionSource {
- id: u64,
- }
-
- pub struct FileInfo {
- pub file_name: OsString,
- pub file_type: FileType,
- /// Local modification time in seconds since the Unix epoch. Only valid for files and symlinks,
- /// not for directories.
- pub local_modification_time: Option<u64>,
- /// Local size of the file in bytes. Only valid for files and symlinks, not for directories.
- pub local_size: Option<u64>,
- // TODO
- }
-
- #[derive(PartialEq)]
- pub enum FileType {
- File,
- Directory,
- Symlink,
- }
-
- impl FileType {
- pub fn from(ft: fs::FileType) -> Option<FileType> {
- if ft.is_file() {
- Some(FileType::File)
- } else if ft.is_dir() {
- Some(FileType::Directory)
- } else if ft.is_symlink() {
- Some(FileType::Symlink)
- } else {
- None
- }
- }
- }
-
- pub struct TemporaryFile {
- // TODO
- }
-
- pub enum OriginInfo {
- Local,
- // TODO: For remote sources, include the previous version to detect conflicts?
- Remote,
- }
|