Skip to main content

disk_core/
lib.rs

1//! The base crate under every rusty-backup filesystem, partition and disk-image crate.
2//!
3//! Always available:
4//! - [`io_other`] / [`repeat_n`]: std shims that build on both current Rust and
5//!   Rust 1.73 (the last toolchain whose std targets macOS 10.7).
6//! - [`display`]: small neutral formatters (sizes, Mac `OSType`, Unix modes).
7//! - [`bits`]: big-endian allocation-bitmap helpers (HFS, HFS+, ProDOS).
8//! - [`sgi`]: the 16-bit word order of SGI disk images.
9//! - `rust173` (feature `rust173-polyfill` only): extension traits standing in
10//!   for std methods missing on 1.73. Never enable it on a modern toolchain.
11//!
12//! With the `fs` feature (on by default), the interface every filesystem crate
13//! (`fs-8bit`, `fs-mac`, …) implements:
14//! - [`filesystem`]: `Filesystem` (read) and `EditableFilesystem` (write),
15//!   `FilesystemError`, create/repair options.
16//! - [`attrs`]: resolve the attributes a copied or imported entry should get.
17//! - [`entry`]: `FileEntry`, `EntryType` and directory display ordering.
18//! - [`id_names`]: uid / gid names from an image's own `/etc/passwd` and `/etc/group`.
19//! - [`fsck`]: integrity-check results shared by every checker.
20//! - [`times`]: Unix timestamps and the calendar conversions filesystems need.
21//! - [`xattr`]: extended-attribute names and values.
22//! - [`unix_common`]: inode helpers (timestamps, permission bits, uid / gid width) shared by every family with Unix-style metadata.
23//! - [`name_legalize`]: turn any name into one a destination's `validate_name` accepts.
24//! - [`raw_name`]: keep non-UTF-8 name bytes intact through a `String`.
25//! - [`stream_pipe`]: copy a file between two filesystems without holding it in memory.
26//!
27//! Partition and disk-image crates depend on this with `default-features = false`
28//! and so build without the filesystem types and their dependencies.
29
30// `is_multiple_of` & co. come from the rust173 polyfill on 1.73; the real floor check is a 1.73 build.
31#![allow(clippy::incompatible_msrv)]
32
33pub mod bits;
34pub mod display;
35#[cfg(feature = "rust173-polyfill")]
36pub mod rust173;
37pub mod sgi;
38
39#[cfg(feature = "fs")]
40pub mod attrs;
41#[cfg(feature = "fs")]
42pub mod entry;
43#[cfg(feature = "fs")]
44pub mod filesystem;
45#[cfg(feature = "fs")]
46pub mod fsck;
47#[cfg(feature = "fs")]
48pub mod id_names;
49#[cfg(feature = "fs")]
50pub mod name_legalize;
51#[cfg(feature = "fs")]
52pub mod raw_name;
53#[cfg(feature = "fs")]
54pub mod stream_pipe;
55#[cfg(feature = "fs")]
56pub mod times;
57#[cfg(feature = "fs")]
58pub mod unix_common;
59#[cfg(feature = "fs")]
60pub mod xattr;
61
62/// Construct an `io::Error` of kind `Other` wrapping `error`.
63///
64/// Modern: `io::Error::other` (stable since Rust 1.74). Vintage (1.73): the
65/// equivalent `io::Error::new(ErrorKind::Other, ..)`.
66#[inline]
67pub fn io_other<E>(error: E) -> std::io::Error
68where
69    E: Into<Box<dyn std::error::Error + Send + Sync>>,
70{
71    #[cfg(not(feature = "rust173-polyfill"))]
72    {
73        std::io::Error::other(error)
74    }
75    #[cfg(feature = "rust173-polyfill")]
76    {
77        std::io::Error::new(std::io::ErrorKind::Other, error)
78    }
79}
80
81/// An iterator that repeats `value` exactly `count` times.
82///
83/// Modern: `iter::repeat_n` (stable since Rust 1.87). Vintage (1.73): the
84/// equivalent `iter::repeat(value).take(count)`.
85#[inline]
86pub fn repeat_n<T: Clone>(value: T, count: usize) -> impl Iterator<Item = T> {
87    #[cfg(not(feature = "rust173-polyfill"))]
88    {
89        std::iter::repeat_n(value, count)
90    }
91    #[cfg(feature = "rust173-polyfill")]
92    {
93        std::iter::repeat(value).take(count)
94    }
95}