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) │
└─────┴─────┴─────┴────────────────────┘| Bit | Meaning |
|---|---|
r (4) | Read permission |
w (2) | Write permission |
x (1) | Execute/search permission |
§Common Permission Values
| Mode | Meaning |
|---|---|
0o644 | Owner read/write, others read (typical file) |
0o755 | Owner all, others read/execute (typical directory) |
0o600 | Owner read/write only (private file) |
0o444 | Everyone 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-xImplementations§
Source§impl Permissions
impl Permissions
Sourcepub const fn default_file() -> Self
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(¤t);
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
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(¤t) {
453 dirs.insert(current.clone());
454 drop(dirs);
455 self.assign_inode(¤t);
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 }Sourcepub const fn default_dir() -> Self
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
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
impl Clone for Permissions
Source§fn clone(&self) -> Permissions
fn clone(&self) -> Permissions
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for Permissions
impl Debug for Permissions
Source§impl Default for Permissions
impl Default for Permissions
Source§impl Hash for Permissions
impl Hash for Permissions
Source§impl PartialEq for Permissions
impl PartialEq for Permissions
impl Copy for Permissions
impl Eq for Permissions
impl StructuralPartialEq for Permissions
Auto Trait Implementations§
impl Freeze for Permissions
impl RefUnwindSafe for Permissions
impl Send for Permissions
impl Sync for Permissions
impl Unpin for Permissions
impl UnwindSafe for Permissions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more