simple_fatfs/
lib.rs

1//! # simple-fatfs
2//!
3//! An easy-to-use FAT filesystem library designed for usage in embedded systems
4//!
5//! ## Features
6//!
7//! - `no_std` support
8//! - FAT12/16/32 support
9//! - VFAT/LFN (long filenames) support
10//! - Auto-`impl`s for [`std::io`] traits and structs
11//! - Easy-to-implement [`io`] traits
12//!
13//! ## Usage
14//!
15//! The library uses [`embedded-io`](embedded_io) for IO operations.
16//! Most notably, the storage medium is expected to implement at least the
17//! [`Read`] and [`Seek`] traits (RO storage), while [`Write`] is optional
18//! (R/W storage). Furthermore, [`ROFile`] & [`RWFile`] both implement [`Read`]
19//! & [`Seek`], while [`RWFile`] also implements [`Write`]
20//!
21//! To use [`std::io`]'s respective traits, use the
22//! [`embedded-io-adapters`](https://crates.io/crates/embedded-io-adapters) crate.
23//!
24//! ## Examples
25//! ```
26//! # // this test fails on a no_std environment, don't run it in such a case
27//! extern crate simple_fatfs;
28//! use simple_fatfs::*;
29//! use simple_fatfs::io::*;
30//!
31//! use embedded_io_adapters::std::FromStd;
32//!
33//! const FAT_IMG: &[u8] = include_bytes!("../imgs/fat12.img");
34//!
35//! fn main() {
36//!     let mut cursor = FromStd::new(std::io::Cursor::new(FAT_IMG.to_owned()));
37//!
38//!     // We can either pass by value or by (mutable) reference
39//!     // (Yes, the storage medium might be Read-Only, but reading is a mutable action)
40//!     let mut fs = FileSystem::new(&mut cursor, FSOptions::new()).unwrap();
41//!
42//!     // Let's see what entries there are in the root directory
43//!     for entry in fs.read_dir("/").unwrap() {
44//!         // in a real world example, you probably don't wanna unwrap this
45//!         let entry = entry.unwrap();
46//!
47//!         if entry.is_dir() {
48//!             println!("Directory: {}", entry.path())
49//!         } else if entry.is_file() {
50//!             println!("File: {}", entry.path())
51//!         } else {
52//!             unreachable!()
53//!         }
54//!     }
55//!
56//!     // the disk image we currently use has a file named "root.txt"
57//!     // in the root directory. Let's read it
58//!     let mut file = fs.get_ro_file("/root.txt").unwrap();
59//!     let mut file_buf = vec![0; file.file_size() as usize];
60//!     file.read_exact(&mut file_buf).unwrap();
61//!     let string = str::from_utf8(&file_buf).unwrap();
62//!     println!("root.txt contents:\n{}", string);
63//! }
64//! ```
65//!
66//! [`Read`]: io::Read
67//! [`Seek`]: io::Seek
68//! [`Write`]: io::Write
69
70#![cfg_attr(not(feature = "std"), no_std)]
71// Even inside unsafe functions, we must acknowlegde the usage of unsafe code
72#![deny(deprecated)]
73#![deny(macro_use_extern_crate)]
74#![deny(private_bounds)]
75#![deny(private_interfaces)]
76#![deny(unsafe_op_in_unsafe_fn)]
77#![warn(missing_copy_implementations)]
78#![warn(missing_debug_implementations)]
79#![warn(missing_docs)]
80#![warn(non_ascii_idents)]
81#![warn(trivial_numeric_casts)]
82#![warn(single_use_lifetimes)]
83#![warn(unused_import_braces)]
84#![warn(unused_lifetimes)]
85// clippy attributes
86#![warn(clippy::absurd_extreme_comparisons)] // who thought this was a good idea for a deny lint?
87#![warn(clippy::derive_partial_eq_without_eq)]
88#![warn(clippy::cast_lossless)]
89#![warn(clippy::cast_possible_truncation)]
90#![warn(clippy::cast_possible_wrap)]
91#![warn(clippy::cast_precision_loss)]
92#![warn(clippy::cast_sign_loss)]
93#![warn(clippy::redundant_clone)]
94
95extern crate alloc;
96
97mod codepage;
98mod error;
99mod fat;
100mod path;
101mod time;
102mod utils;
103
104pub use codepage::*;
105pub use embedded_io as io;
106pub use error::*;
107pub use fat::*;
108pub use path::*;
109pub use time::*;