Permissions

Struct Permissions 

Source
pub struct Permissions(/* private fields */);
Expand description

Unix-style permission bits.

Stores permissions as a standard Unix mode bitmask (rwxrwxrwx format). The lower 12 bits represent: owner (rwx), group (rwx), other (rwx), plus setuid/setgid/sticky bits.

§Permission Bits

Mode: 0o7777 (octal)
┌─────┬─────┬─────┬────────────────────┐
│ Special │ Owner │ Group │ Other        │
│ (sst)   │ (rwx) │ (rwx) │ (rwx)        │
└─────┴─────┴─────┴────────────────────┘
BitMeaning
r (4)Read permission
w (2)Write permission
x (1)Execute/search permission

§Common Permission Values

ModeMeaning
0o644Owner read/write, others read (typical file)
0o755Owner all, others read/execute (typical directory)
0o600Owner read/write only (private file)
0o444Everyone read only

§Example

use anyfs_backend::Permissions;

// Create from octal mode
let perm = Permissions::from_mode(0o755);
assert_eq!(perm.mode(), 0o755);
assert!(!perm.readonly());

// Read-only permissions
let readonly = Permissions::from_mode(0o444);
assert!(readonly.readonly());

// Default permissions
assert_eq!(Permissions::default_file().mode(), 0o644);  // rw-r--r--
assert_eq!(Permissions::default_dir().mode(), 0o755);   // rwxr-xr-x

Implementations§

Source§

impl Permissions

Source

pub const fn from_mode(mode: u32) -> Self

Create permissions from a Unix mode (e.g., 0o755).

Source

pub const fn mode(&self) -> u32

Get the raw mode value.

Source

pub const fn readonly(&self) -> bool

Returns true if these permissions deny writing.

Source

pub const fn default_file() -> Self

Default permissions for a new file (0o644 = rw-r–r–).

Examples found in repository?
examples/generic_functions.rs (line 340)
323    fn metadata(&self, path: &Path) -> Result<Metadata, FsError> {
324        let ft = self.get_file_type(path).ok_or_else(|| FsError::NotFound {
325            path: path.to_path_buf(),
326        })?;
327        let size = if ft == FileType::File {
328            self.files
329                .read()
330                .unwrap()
331                .get(path)
332                .map(|d| d.len() as u64)
333                .unwrap_or(0)
334        } else {
335            0
336        };
337        Ok(Metadata {
338            file_type: ft,
339            size,
340            permissions: Permissions::default_file(),
341            created: SystemTime::UNIX_EPOCH,
342            modified: SystemTime::UNIX_EPOCH,
343            accessed: SystemTime::UNIX_EPOCH,
344            inode: self.inodes.read().unwrap().get(path).copied().unwrap_or(0),
345            nlink: 1,
346        })
347    }
348    fn open_read(&self, path: &Path) -> Result<Box<dyn Read + Send>, FsError> {
349        Ok(Box::new(std::io::Cursor::new(self.read(path)?)))
350    }
351}
352
353impl FsWrite for DemoFs {
354    fn write(&self, path: &Path, data: &[u8]) -> Result<(), FsError> {
355        self.assign_inode(path);
356        self.files
357            .write()
358            .unwrap()
359            .insert(path.to_path_buf(), data.to_vec());
360        Ok(())
361    }
362    fn append(&self, path: &Path, data: &[u8]) -> Result<(), FsError> {
363        self.files
364            .write()
365            .unwrap()
366            .entry(path.to_path_buf())
367            .or_default()
368            .extend_from_slice(data);
369        self.assign_inode(path);
370        Ok(())
371    }
372    fn remove_file(&self, path: &Path) -> Result<(), FsError> {
373        self.files
374            .write()
375            .unwrap()
376            .remove(path)
377            .map(|_| ())
378            .ok_or_else(|| FsError::NotFound {
379                path: path.to_path_buf(),
380            })
381    }
382    fn rename(&self, from: &Path, to: &Path) -> Result<(), FsError> {
383        let data = self
384            .files
385            .write()
386            .unwrap()
387            .remove(from)
388            .ok_or_else(|| FsError::NotFound {
389                path: from.to_path_buf(),
390            })?;
391        self.files.write().unwrap().insert(to.to_path_buf(), data);
392        self.assign_inode(to);
393        Ok(())
394    }
395    fn copy(&self, from: &Path, to: &Path) -> Result<(), FsError> {
396        let data = self.read(from)?;
397        self.write(to, &data)
398    }
399    fn truncate(&self, path: &Path, size: u64) -> Result<(), FsError> {
400        self.files
401            .write()
402            .unwrap()
403            .get_mut(path)
404            .ok_or_else(|| FsError::NotFound {
405                path: path.to_path_buf(),
406            })?
407            .resize(size as usize, 0);
408        Ok(())
409    }
410    fn open_write(&self, _path: &Path) -> Result<Box<dyn Write + Send>, FsError> {
411        Ok(Box::new(std::io::Cursor::new(Vec::new())))
412    }
413}
414
415impl FsDir for DemoFs {
416    fn read_dir(&self, path: &Path) -> Result<ReadDirIter, FsError> {
417        if !self.dirs.read().unwrap().contains(path) {
418            return Err(FsError::NotFound {
419                path: path.to_path_buf(),
420            });
421        }
422        let mut entries = Vec::new();
423        for (fp, data) in self.files.read().unwrap().iter() {
424            if fp.parent() == Some(path) {
425                if let Some(name) = fp.file_name() {
426                    entries.push(Ok(DirEntry {
427                        name: name.to_string_lossy().into(),
428                        path: fp.clone(),
429                        file_type: FileType::File,
430                        size: data.len() as u64,
431                        inode: 0,
432                    }));
433                }
434            }
435        }
436        for dp in self.dirs.read().unwrap().iter() {
437            if dp.parent() == Some(path) && dp != path {
438                if let Some(name) = dp.file_name() {
439                    entries.push(Ok(DirEntry {
440                        name: name.to_string_lossy().into(),
441                        path: dp.clone(),
442                        file_type: FileType::Directory,
443                        size: 0,
444                        inode: 0,
445                    }));
446                }
447            }
448        }
449        Ok(ReadDirIter::from_vec(entries))
450    }
451    fn create_dir(&self, path: &Path) -> Result<(), FsError> {
452        if self.dirs.read().unwrap().contains(path) {
453            return Err(FsError::AlreadyExists {
454                path: path.to_path_buf(),
455                operation: "create_dir",
456            });
457        }
458        self.dirs.write().unwrap().insert(path.to_path_buf());
459        self.assign_inode(path);
460        Ok(())
461    }
462    fn create_dir_all(&self, path: &Path) -> Result<(), FsError> {
463        let mut current = PathBuf::new();
464        for c in path.components() {
465            current.push(c);
466            self.dirs.write().unwrap().insert(current.clone());
467            self.assign_inode(&current);
468        }
469        Ok(())
470    }
471    fn remove_dir(&self, path: &Path) -> Result<(), FsError> {
472        if !self.dirs.write().unwrap().remove(path) {
473            return Err(FsError::NotFound {
474                path: path.to_path_buf(),
475            });
476        }
477        Ok(())
478    }
479    fn remove_dir_all(&self, path: &Path) -> Result<(), FsError> {
480        self.dirs.write().unwrap().remove(path);
481        self.files
482            .write()
483            .unwrap()
484            .retain(|p, _| !p.starts_with(path));
485        Ok(())
486    }
487}
488
489impl FsLink for DemoFs {
490    fn symlink(&self, target: &Path, link: &Path) -> Result<(), FsError> {
491        self.symlinks
492            .write()
493            .unwrap()
494            .insert(link.to_path_buf(), target.to_path_buf());
495        self.assign_inode(link);
496        Ok(())
497    }
498    fn hard_link(&self, original: &Path, link: &Path) -> Result<(), FsError> {
499        let data = self.read(original)?;
500        self.write(link, &data)
501    }
502    fn read_link(&self, path: &Path) -> Result<PathBuf, FsError> {
503        self.symlinks
504            .read()
505            .unwrap()
506            .get(path)
507            .cloned()
508            .ok_or_else(|| FsError::InvalidData {
509                path: path.to_path_buf(),
510                details: "not a symlink".into(),
511            })
512    }
513    fn symlink_metadata(&self, path: &Path) -> Result<Metadata, FsError> {
514        let ft = self.get_file_type(path).ok_or_else(|| FsError::NotFound {
515            path: path.to_path_buf(),
516        })?;
517        Ok(Metadata {
518            file_type: ft,
519            size: 0,
520            permissions: Permissions::default_file(),
521            created: SystemTime::UNIX_EPOCH,
522            modified: SystemTime::UNIX_EPOCH,
523            accessed: SystemTime::UNIX_EPOCH,
524            inode: 0,
525            nlink: 1,
526        })
527    }
More examples
Hide additional examples
examples/inmemory_fs.rs (line 220)
199    fn metadata(&self, path: &Path) -> Result<Metadata, FsError> {
200        let file_type = self.get_file_type(path).ok_or_else(|| FsError::NotFound {
201            path: path.to_path_buf(),
202        })?;
203
204        let size = if file_type == FileType::File {
205            self.files
206                .read()
207                .unwrap()
208                .get(path)
209                .map(|d| d.len() as u64)
210                .unwrap_or(0)
211        } else {
212            0
213        };
214
215        let inode = self.inodes.read().unwrap().get(path).copied().unwrap_or(0);
216
217        Ok(Metadata {
218            file_type,
219            size,
220            permissions: Permissions::default_file(),
221            created: SystemTime::UNIX_EPOCH,
222            modified: SystemTime::UNIX_EPOCH,
223            accessed: SystemTime::UNIX_EPOCH,
224            inode,
225            nlink: 1,
226        })
227    }
228
229    fn open_read(&self, path: &Path) -> Result<Box<dyn Read + Send>, FsError> {
230        let data = self.read(path)?;
231        Ok(Box::new(std::io::Cursor::new(data)))
232    }
233}
234
235// =============================================================================
236// Layer 1: FsWrite - Writing and modifying files
237// =============================================================================
238
239impl FsWrite for InMemoryFs {
240    fn write(&self, path: &Path, data: &[u8]) -> Result<(), FsError> {
241        self.assign_inode(path);
242        self.files
243            .write()
244            .unwrap()
245            .insert(path.to_path_buf(), data.to_vec());
246        Ok(())
247    }
248
249    fn append(&self, path: &Path, data: &[u8]) -> Result<(), FsError> {
250        let mut files = self.files.write().unwrap();
251        files
252            .entry(path.to_path_buf())
253            .or_default()
254            .extend_from_slice(data);
255        drop(files);
256        self.assign_inode(path);
257        Ok(())
258    }
259
260    fn remove_file(&self, path: &Path) -> Result<(), FsError> {
261        self.files
262            .write()
263            .unwrap()
264            .remove(path)
265            .ok_or_else(|| FsError::NotFound {
266                path: path.to_path_buf(),
267            })?;
268
269        // Clean up inode mapping
270        if let Some(inode) = self.inodes.write().unwrap().remove(path) {
271            self.inode_to_path.write().unwrap().remove(&inode);
272        }
273
274        // Clean up xattrs
275        self.xattrs.write().unwrap().remove(path);
276
277        Ok(())
278    }
279
280    fn rename(&self, from: &Path, to: &Path) -> Result<(), FsError> {
281        let mut files = self.files.write().unwrap();
282        let data = files.remove(from).ok_or_else(|| FsError::NotFound {
283            path: from.to_path_buf(),
284        })?;
285        files.insert(to.to_path_buf(), data);
286        drop(files);
287
288        // Update inode mappings
289        if let Some(inode) = self.inodes.write().unwrap().remove(from) {
290            self.inodes.write().unwrap().insert(to.to_path_buf(), inode);
291            self.inode_to_path
292                .write()
293                .unwrap()
294                .insert(inode, to.to_path_buf());
295        } else {
296            self.assign_inode(to);
297        }
298
299        // Move xattrs
300        if let Some(attrs) = self.xattrs.write().unwrap().remove(from) {
301            self.xattrs.write().unwrap().insert(to.to_path_buf(), attrs);
302        }
303
304        Ok(())
305    }
306
307    fn copy(&self, from: &Path, to: &Path) -> Result<(), FsError> {
308        let data = self.read(from)?;
309        self.write(to, &data)
310    }
311
312    fn truncate(&self, path: &Path, size: u64) -> Result<(), FsError> {
313        let mut files = self.files.write().unwrap();
314        let data = files.get_mut(path).ok_or_else(|| FsError::NotFound {
315            path: path.to_path_buf(),
316        })?;
317        data.resize(size as usize, 0);
318        Ok(())
319    }
320
321    fn open_write(&self, path: &Path) -> Result<Box<dyn Write + Send>, FsError> {
322        // Create file if it doesn't exist
323        if !self.files.read().unwrap().contains_key(path) {
324            self.write(path, &[])?;
325        }
326
327        // Return a cursor that writes to a buffer
328        // Note: In a real implementation, this would write back on drop
329        Ok(Box::new(std::io::Cursor::new(Vec::new())))
330    }
331}
332
333// =============================================================================
334// Layer 1: FsDir - Directory operations
335// =============================================================================
336
337impl FsDir for InMemoryFs {
338    fn read_dir(&self, path: &Path) -> Result<ReadDirIter, FsError> {
339        if !self.dirs.read().unwrap().contains(path) {
340            return Err(FsError::NotFound {
341                path: path.to_path_buf(),
342            });
343        }
344
345        let mut entries = Vec::new();
346
347        // Collect files in this directory
348        for (file_path, data) in self.files.read().unwrap().iter() {
349            if let Some(parent) = file_path.parent() {
350                if parent == path {
351                    if let Some(name) = file_path.file_name() {
352                        entries.push(Ok(DirEntry {
353                            name: name.to_string_lossy().into_owned(),
354                            path: file_path.clone(),
355                            file_type: FileType::File,
356                            size: data.len() as u64,
357                            inode: self
358                                .inodes
359                                .read()
360                                .unwrap()
361                                .get(file_path)
362                                .copied()
363                                .unwrap_or(0),
364                        }));
365                    }
366                }
367            }
368        }
369
370        // Collect subdirectories
371        for dir_path in self.dirs.read().unwrap().iter() {
372            if let Some(parent) = dir_path.parent() {
373                if parent == path && dir_path != path {
374                    if let Some(name) = dir_path.file_name() {
375                        entries.push(Ok(DirEntry {
376                            name: name.to_string_lossy().into_owned(),
377                            path: dir_path.clone(),
378                            file_type: FileType::Directory,
379                            size: 0,
380                            inode: self
381                                .inodes
382                                .read()
383                                .unwrap()
384                                .get(dir_path)
385                                .copied()
386                                .unwrap_or(0),
387                        }));
388                    }
389                }
390            }
391        }
392
393        // Collect symlinks
394        for link_path in self.symlinks.read().unwrap().keys() {
395            if let Some(parent) = link_path.parent() {
396                if parent == path {
397                    if let Some(name) = link_path.file_name() {
398                        entries.push(Ok(DirEntry {
399                            name: name.to_string_lossy().into_owned(),
400                            path: link_path.clone(),
401                            file_type: FileType::Symlink,
402                            size: 0,
403                            inode: self
404                                .inodes
405                                .read()
406                                .unwrap()
407                                .get(link_path)
408                                .copied()
409                                .unwrap_or(0),
410                        }));
411                    }
412                }
413            }
414        }
415
416        Ok(ReadDirIter::from_vec(entries))
417    }
418
419    fn create_dir(&self, path: &Path) -> Result<(), FsError> {
420        let mut dirs = self.dirs.write().unwrap();
421
422        if dirs.contains(path) {
423            return Err(FsError::AlreadyExists {
424                path: path.to_path_buf(),
425                operation: "create_dir",
426            });
427        }
428
429        // Check parent exists
430        if let Some(parent) = path.parent() {
431            if parent != Path::new("") && parent != Path::new("/") && !dirs.contains(parent) {
432                return Err(FsError::NotFound {
433                    path: parent.to_path_buf(),
434                });
435            }
436        }
437
438        dirs.insert(path.to_path_buf());
439        drop(dirs);
440        self.assign_inode(path);
441
442        Ok(())
443    }
444
445    fn create_dir_all(&self, path: &Path) -> Result<(), FsError> {
446        let mut current = PathBuf::new();
447
448        for component in path.components() {
449            current.push(component);
450
451            let mut dirs = self.dirs.write().unwrap();
452            if !dirs.contains(&current) {
453                dirs.insert(current.clone());
454                drop(dirs);
455                self.assign_inode(&current);
456            }
457        }
458
459        Ok(())
460    }
461
462    fn remove_dir(&self, path: &Path) -> Result<(), FsError> {
463        // Check if directory is empty
464        let has_files = self
465            .files
466            .read()
467            .unwrap()
468            .keys()
469            .any(|p| p.parent() == Some(path));
470
471        let has_subdirs = self
472            .dirs
473            .read()
474            .unwrap()
475            .iter()
476            .any(|p| p.parent() == Some(path) && p != path);
477
478        if has_files || has_subdirs {
479            return Err(FsError::DirectoryNotEmpty {
480                path: path.to_path_buf(),
481            });
482        }
483
484        if !self.dirs.write().unwrap().remove(path) {
485            return Err(FsError::NotFound {
486                path: path.to_path_buf(),
487            });
488        }
489
490        // Clean up inode
491        if let Some(inode) = self.inodes.write().unwrap().remove(path) {
492            self.inode_to_path.write().unwrap().remove(&inode);
493        }
494
495        Ok(())
496    }
497
498    fn remove_dir_all(&self, path: &Path) -> Result<(), FsError> {
499        // Remove all files under this path
500        self.files
501            .write()
502            .unwrap()
503            .retain(|p, _| !p.starts_with(path));
504
505        // Remove all subdirectories under this path
506        self.dirs.write().unwrap().retain(|p| !p.starts_with(path));
507
508        // Remove all symlinks under this path
509        self.symlinks
510            .write()
511            .unwrap()
512            .retain(|p, _| !p.starts_with(path));
513
514        // Clean up inodes
515        let paths_to_remove: Vec<_> = self
516            .inodes
517            .read()
518            .unwrap()
519            .keys()
520            .filter(|p| p.starts_with(path))
521            .cloned()
522            .collect();
523
524        for p in paths_to_remove {
525            if let Some(inode) = self.inodes.write().unwrap().remove(&p) {
526                self.inode_to_path.write().unwrap().remove(&inode);
527            }
528        }
529
530        Ok(())
531    }
532}
533
534// =============================================================================
535// Layer 2: FsLink - Symbolic and hard links
536// =============================================================================
537
538impl FsLink for InMemoryFs {
539    fn symlink(&self, target: &Path, link: &Path) -> Result<(), FsError> {
540        if self.get_file_type(link).is_some() {
541            return Err(FsError::AlreadyExists {
542                path: link.to_path_buf(),
543                operation: "symlink",
544            });
545        }
546
547        self.symlinks
548            .write()
549            .unwrap()
550            .insert(link.to_path_buf(), target.to_path_buf());
551        self.assign_inode(link);
552
553        Ok(())
554    }
555
556    fn hard_link(&self, original: &Path, link: &Path) -> Result<(), FsError> {
557        // For in-memory fs, we just copy the data (true hard links would share data)
558        let data = self.read(original)?;
559        self.write(link, &data)?;
560
561        // In a real implementation, you'd update nlink count
562        Ok(())
563    }
564
565    fn read_link(&self, path: &Path) -> Result<PathBuf, FsError> {
566        self.symlinks
567            .read()
568            .unwrap()
569            .get(path)
570            .cloned()
571            .ok_or_else(|| FsError::InvalidData {
572                path: path.to_path_buf(),
573                details: "not a symbolic link".into(),
574            })
575    }
576
577    fn symlink_metadata(&self, path: &Path) -> Result<Metadata, FsError> {
578        let file_type = self.get_file_type(path).ok_or_else(|| FsError::NotFound {
579            path: path.to_path_buf(),
580        })?;
581
582        Ok(Metadata {
583            file_type,
584            size: 0,
585            permissions: Permissions::default_file(),
586            created: SystemTime::UNIX_EPOCH,
587            modified: SystemTime::UNIX_EPOCH,
588            accessed: SystemTime::UNIX_EPOCH,
589            inode: self.inodes.read().unwrap().get(path).copied().unwrap_or(0),
590            nlink: 1,
591        })
592    }
examples/basic_usage.rs (line 92)
76    fn metadata(&self, path: &Path) -> Result<Metadata, FsError> {
77        if self.dirs.read().unwrap().contains(path) {
78            Ok(Metadata {
79                file_type: FileType::Directory,
80                size: 0,
81                permissions: Permissions::default_dir(),
82                created: SystemTime::UNIX_EPOCH,
83                modified: SystemTime::UNIX_EPOCH,
84                accessed: SystemTime::UNIX_EPOCH,
85                inode: 0,
86                nlink: 1,
87            })
88        } else if let Some(data) = self.files.read().unwrap().get(path) {
89            Ok(Metadata {
90                file_type: FileType::File,
91                size: data.len() as u64,
92                permissions: Permissions::default_file(),
93                created: SystemTime::UNIX_EPOCH,
94                modified: SystemTime::UNIX_EPOCH,
95                accessed: SystemTime::UNIX_EPOCH,
96                inode: 0,
97                nlink: 1,
98            })
99        } else {
100            Err(FsError::NotFound {
101                path: path.to_path_buf(),
102            })
103        }
104    }
examples/layer_middleware.rs (line 495)
479    fn metadata(&self, path: &Path) -> Result<Metadata, FsError> {
480        if self.dirs.read().unwrap().contains(path) {
481            Ok(Metadata {
482                file_type: FileType::Directory,
483                size: 0,
484                permissions: Permissions::default_dir(),
485                created: SystemTime::UNIX_EPOCH,
486                modified: SystemTime::UNIX_EPOCH,
487                accessed: SystemTime::UNIX_EPOCH,
488                inode: 0,
489                nlink: 1,
490            })
491        } else if let Some(data) = self.files.read().unwrap().get(path) {
492            Ok(Metadata {
493                file_type: FileType::File,
494                size: data.len() as u64,
495                permissions: Permissions::default_file(),
496                created: SystemTime::UNIX_EPOCH,
497                modified: SystemTime::UNIX_EPOCH,
498                accessed: SystemTime::UNIX_EPOCH,
499                inode: 0,
500                nlink: 1,
501            })
502        } else {
503            Err(FsError::NotFound {
504                path: path.to_path_buf(),
505            })
506        }
507    }
Source

pub const fn default_dir() -> Self

Default permissions for a new directory (0o755 = rwxr-xr-x).

Examples found in repository?
examples/basic_usage.rs (line 81)
76    fn metadata(&self, path: &Path) -> Result<Metadata, FsError> {
77        if self.dirs.read().unwrap().contains(path) {
78            Ok(Metadata {
79                file_type: FileType::Directory,
80                size: 0,
81                permissions: Permissions::default_dir(),
82                created: SystemTime::UNIX_EPOCH,
83                modified: SystemTime::UNIX_EPOCH,
84                accessed: SystemTime::UNIX_EPOCH,
85                inode: 0,
86                nlink: 1,
87            })
88        } else if let Some(data) = self.files.read().unwrap().get(path) {
89            Ok(Metadata {
90                file_type: FileType::File,
91                size: data.len() as u64,
92                permissions: Permissions::default_file(),
93                created: SystemTime::UNIX_EPOCH,
94                modified: SystemTime::UNIX_EPOCH,
95                accessed: SystemTime::UNIX_EPOCH,
96                inode: 0,
97                nlink: 1,
98            })
99        } else {
100            Err(FsError::NotFound {
101                path: path.to_path_buf(),
102            })
103        }
104    }
More examples
Hide additional examples
examples/layer_middleware.rs (line 484)
479    fn metadata(&self, path: &Path) -> Result<Metadata, FsError> {
480        if self.dirs.read().unwrap().contains(path) {
481            Ok(Metadata {
482                file_type: FileType::Directory,
483                size: 0,
484                permissions: Permissions::default_dir(),
485                created: SystemTime::UNIX_EPOCH,
486                modified: SystemTime::UNIX_EPOCH,
487                accessed: SystemTime::UNIX_EPOCH,
488                inode: 0,
489                nlink: 1,
490            })
491        } else if let Some(data) = self.files.read().unwrap().get(path) {
492            Ok(Metadata {
493                file_type: FileType::File,
494                size: data.len() as u64,
495                permissions: Permissions::default_file(),
496                created: SystemTime::UNIX_EPOCH,
497                modified: SystemTime::UNIX_EPOCH,
498                accessed: SystemTime::UNIX_EPOCH,
499                inode: 0,
500                nlink: 1,
501            })
502        } else {
503            Err(FsError::NotFound {
504                path: path.to_path_buf(),
505            })
506        }
507    }

Trait Implementations§

Source§

impl Clone for Permissions

Source§

fn clone(&self) -> Permissions

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Permissions

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Permissions

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Hash for Permissions

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Permissions

Source§

fn eq(&self, other: &Permissions) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for Permissions

Source§

impl Eq for Permissions

Source§

impl StructuralPartialEq for Permissions

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.