embedded_fat/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
//! # embedded-sdmmc
//!
//! > An SD/MMC Library written in Embedded Rust
//!
//! This crate is intended to allow you to read/write files on a FAT formatted
//! SD card on your Rust Embedded device, as easily as using the `SdFat` Arduino
//! library. It is written in pure-Rust, is `#![no_std]` and does not use
//! `alloc` or `collections` to keep the memory footprint low. In the first
//! instance it is designed for readability and simplicity over performance.
//!
//! ## Using the crate
//!
//! You will need something that implements the `BlockDevice` trait, which can
//! read and write the 512-byte blocks (or sectors) from your card. If you were
//! to implement this over USB Mass Storage, there's no reason this crate
//! couldn't work with a USB Thumb Drive, but we only supply a `BlockDevice`
//! suitable for reading SD and SDHC cards over SPI.
//!
//! ## Features
//!
//! * `log`: Enabled by default. Generates log messages using the `log` crate.
//! * `defmt-log`: By turning off the default features and enabling the
//! `defmt-log` feature you can configure this crate to log messages over defmt
//! instead.
//!
//! You cannot enable both the `log` feature and the `defmt-log` feature.
#![cfg_attr(not(test), no_std)]
#![feature(async_fn_in_trait)]
#![deny(missing_docs)]
// ****************************************************************************
//
// Imports
//
// ****************************************************************************
#[cfg(test)]
#[macro_use]
extern crate hex_literal;
#[macro_use]
mod structure;
pub mod blockdevice;
pub mod fat;
pub mod filesystem;
#[doc(inline)]
pub use crate::blockdevice::{Block, BlockCount, BlockDevice, BlockIdx};
#[doc(inline)]
pub use crate::fat::FatVolume;
#[doc(inline)]
pub use crate::filesystem::{
Attributes, ClusterId, DirEntry, Directory, File, FilenameError, Mode, ShortFileName,
TimeSource, Timestamp, MAX_FILE_SIZE,
};
use filesystem::DirectoryInfo;
mod volume;
#[doc(inline)]
pub use volume::Volume;
#[cfg(all(feature = "defmt-log", feature = "log"))]
compile_error!("Cannot enable both log and defmt-log");
#[cfg(feature = "log")]
use log::{debug, trace, warn};
#[cfg(feature = "defmt-log")]
use defmt::{debug, trace, warn};
#[cfg(all(not(feature = "defmt-log"), not(feature = "log")))]
#[macro_export]
/// Like log::debug! but does nothing at all
macro_rules! debug {
($($arg:tt)+) => {};
}
#[cfg(all(not(feature = "defmt-log"), not(feature = "log")))]
#[macro_export]
/// Like log::trace! but does nothing at all
macro_rules! trace {
($($arg:tt)+) => {};
}
#[cfg(all(not(feature = "defmt-log"), not(feature = "log")))]
#[macro_export]
/// Like log::warn! but does nothing at all
macro_rules! warn {
($($arg:tt)+) => {};
}
// ****************************************************************************
//
// Public Types
//
// ****************************************************************************
/// Represents all the ways the functions in this crate can fail.
#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
#[derive(Debug, Clone)]
pub enum Error<E>
where
E: core::fmt::Debug,
{
/// The underlying block device threw an error.
DeviceError(E),
/// The filesystem is badly formatted (or this code is buggy).
FormatError(&'static str),
/// The given `VolumeIdx` was bad,
NoSuchVolume,
/// The given filename was bad
FilenameError(FilenameError),
/// Out of memory opening volumes
TooManyOpenVolumes,
/// Out of memory opening directories
TooManyOpenDirs,
/// Out of memory opening files
TooManyOpenFiles,
/// Bad handle given
BadHandle,
/// That file doesn't exist
FileNotFound,
/// You can't open a file twice or delete an open file
FileAlreadyOpen,
/// You can't open a directory twice
DirAlreadyOpen,
/// You can't open a directory as a file
OpenedDirAsFile,
/// You can't open a file as a directory
OpenedFileAsDir,
/// You can't delete a directory as a file
DeleteDirAsFile,
/// You can't close a volume with open files or directories
VolumeStillInUse,
/// You can't open a volume twice
VolumeAlreadyOpen,
/// We can't do that yet
Unsupported,
/// Tried to read beyond end of file
EndOfFile,
/// Found a bad cluster
BadCluster,
/// Error while converting types
ConversionError,
/// The device does not have enough space for the operation
NotEnoughSpace,
/// Cluster was not properly allocated by the library
AllocationError,
/// Jumped to free space during FAT traversing
UnterminatedFatChain,
/// Tried to open Read-Only file with write mode
ReadOnly,
/// Tried to create an existing file
FileAlreadyExists,
/// Bad block size - only 512 byte blocks supported
BadBlockSize(u16),
/// Bad offset given when seeking
InvalidOffset,
}
impl<E> From<E> for Error<E>
where
E: core::fmt::Debug,
{
fn from(value: E) -> Error<E> {
Error::DeviceError(value)
}
}
/// This enum holds the data for the various different types of filesystems we
/// support.
#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
#[derive(Debug, PartialEq, Eq)]
pub enum VolumeType {
/// FAT16/FAT32 formatted volumes.
Fat(FatVolume),
}
// ****************************************************************************
//
// Unit Tests
//
// ****************************************************************************
// None