blob: b0d9f4e7b1bdf6cc2d09791d31288e99e65116e7 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! A helper to create files backed by in process callbacks. For example to expose component
//! configuration, debug information or statistics.
#![recursion_limit = "1024"]
#![allow(unused_extern_crates)]
use proc_macro_hack::proc_macro_hack;
#[macro_use]
pub mod test_utils;
pub mod directory;
pub mod file;
pub mod tree_builder;
mod common;
// --- pseudo_directory ---
// pseudo_directory! uses helper functions that live in this module. It needs to be accessible
// from the outside of this crate.
#[doc(hidden)]
pub mod pseudo_directory;
/// Builds a pseudo directory using a simple DSL, potentially containing files and nested pseudo directories.
///
/// A directory is described using a sequence of rules of the following form:
///
/// <name> `=>` <something that implements DirectoryEntry>
///
/// separated by commas, with an optional trailing comma.
///
/// It generates a nested pseudo directory, using [`directory::empty`] then adding all the
/// specified entries in it, by calling [`directory::PseudoDirectory::add_entry`].
///
/// Note: At the moment duplicate entry names are not checked statically. Duplicate entries will
/// cause panic when the pseudo directory will be constructed at run time. The error message will
/// contain details on the location of the generating macro and the duplicate entry name.
///
/// # Examples
///
/// This will construct a small tree of read-only files:
/// ```
/// let root = pseudo_directory! {
/// "etc" => pseudo_directory! {
/// "fstab" => read_only_static(b"/dev/fs /"),
/// "passwd" => read_only_static(b"[redacted]"),
/// "shells" => read_only_static(b"/bin/bash"),
/// "ssh" => pseudo_directory! {
/// "sshd_config" => read_only_static(b"# Empty"),
/// },
/// },
/// "uname" => read_only_static(b"Fuchsia"),
/// };
/// ```
///
/// An example of a tree with a writable file:
/// ```
/// let write_count = &RefCell::new(0);
/// let root = pseudo_directory! {
/// "etc" => pseudo_directory! {
/// "sshd_config" => read_write(
/// || Ok(b"# Empty".to_vec()),
/// 100,
/// |content| {
/// let mut count = write_count.borrow_mut();
/// assert_eq!(*&content, format!("Port {}", 22 + *count).as_bytes());
/// *count += 1;
/// Ok(())
/// }),
/// },
/// };
/// ```
///
/// You can specify the POSIX attributes for the pseudo directory, by providing the attributes as
/// an expression, fater a "protection_attributes" keyword followed by a comma, with a `;`
/// separating it from the entry definitions:
/// ```
/// let root = pseudo_directory! {
/// "etc" => pseudo_directory! {
/// protection_attributes: S_IXOTH | S_IROTH | S_IXGRP | S_IRGRP | S_IXUSR | S_IRUSR;
/// "fstab" => read_only_attr(S_IROTH | S_IRGRP | S_IRUSR,
/// || Ok(b"/dev/fs /".to_vec())),
/// "passwd" => read_only(S_IRUSR, || Ok(b"[redacted]".to_vec())),
/// },
/// };
/// ```
#[proc_macro_hack(support_nested)]
pub use fuchsia_vfs_pseudo_fs_macros::pseudo_directory;
// This allows the pseudo_directory! macro to use absolute paths within this crate to refer to the
// helper functions. External crates that use pseudo_directory! will rely on the pseudo_directory
// export above.
extern crate self as fuchsia_vfs_pseudo_fs;