bb_flasher_sd/
lib.rs

1//! Library to flash SD cards with OS images. Powers sd card flashing in [BeagleBoard Imager].
2//!
3//! Also allows optional extra [Customization] for BeagleBoard images. Currently only supports
4//! sysconf based post-install configuration.
5//!
6//! # Platform Support
7//!
8//! - Linux
9//! - Windows
10//! - MacOS
11//!
12//! # Features
13//!
14//! - `udev`: Dynamic permissions on Linux. Mostly useful for GUI and flatpaks
15//! - `macos_authopen`: Dynamic permissions on MacOS.
16//!
17//! # Usage
18//!
19//! ```no_run
20//! use std::path::Path;
21//! use std::fs::File;
22//!
23//! let dst = Path::new("/tmp/dummy");
24//! let img = || {
25//!     Ok((File::open("/tmp/image")?, 1024))
26//! };
27//! let (tx, rx) = futures::channel::mpsc::channel(20);
28//!
29//! let flash_thread = std::thread::spawn(move || {
30//!     bb_flasher_sd::flash(
31//!         img,
32//!         dst,
33//!         Some(tx),
34//!         None,
35//!         None
36//!     )
37//! });
38//!
39//! let msgs = futures::executor::block_on_stream(rx);
40//! for m in msgs {
41//!     println!("{:?}", m);
42//! }
43//!
44//! flash_thread.join().unwrap().unwrap()
45//! ```
46//!
47//! [BeagleBoard Imager]: https://openbeagle.org/ayush1325/bb-imager-rs
48
49use std::{io, path::PathBuf};
50
51use thiserror::Error;
52
53pub(crate) mod customization;
54mod flashing;
55mod helpers;
56pub(crate) mod pal;
57
58pub use customization::Customization;
59pub use flashing::flash;
60
61pub(crate) type Result<T, E = Error> = std::result::Result<T, E>;
62
63#[derive(Error, Debug)]
64/// Errors for this crate
65pub enum Error {
66    #[error("Failed to customize flashed image {0}")]
67    Customization(String),
68    #[error("IO Error: {0}")]
69    IoError(#[from] io::Error),
70    /// Aborted before completing
71    #[error("Aborted before completing")]
72    Aborted,
73    #[error("Failed to format SD Card: {0}")]
74    FailedToFormat(String),
75    #[error("Failed to open {0}")]
76    FailedToOpenDestination(String),
77
78    #[error("Udisks2 Error: {0}")]
79    #[cfg(all(feature = "udev", target_os = "linux"))]
80    Udisks(#[from] udisks2::Error),
81
82    #[cfg(windows)]
83    #[error("Drive path is not valid")]
84    InvalidDrive,
85    #[cfg(windows)]
86    #[error("Failed to find the drive {0}")]
87    DriveNotFound(String),
88    #[cfg(windows)]
89    #[error("Windows Error: {0}")]
90    WindowsError(#[from] windows::core::Error),
91}
92
93/// Enumerate all SD Cards in system
94pub fn devices() -> std::collections::HashSet<Device> {
95    bb_drivelist::drive_list()
96        .expect("Unsupported OS for Sd Card")
97        .into_iter()
98        .filter(|x| x.is_removable)
99        .filter(|x| !x.is_virtual)
100        .map(|x| Device::new(x.description, x.raw.into(), x.size))
101        .collect()
102}
103
104#[derive(Hash, Debug, PartialEq, Eq, Clone)]
105/// SD Card
106pub struct Device {
107    pub name: String,
108    pub path: PathBuf,
109    pub size: u64,
110}
111
112impl Device {
113    const fn new(name: String, path: PathBuf, size: u64) -> Self {
114        Self { name, path, size }
115    }
116}
117
118/// Format SD card to fat32
119pub fn format(dst: &std::path::Path) -> Result<()> {
120    crate::pal::format(dst)
121}