Macro vfs::pseudo_directory

pseudo_directory!() { /* proc-macro */ }
Expand description

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:

=>

separated by commas, with an optional trailing comma.

It generates a nested pseudo directory, using directory::immutable::simple() then adding all the specified entries in it, by calling crate::directory::helper::DirectlyMutable::add_entry.

See mut_pseudo_directory! if you want the directory to be modifiable by the clients.

Note: Names specified as literals (both str and [u8]) are compared during compilation time, so you should get a nice error message, if you specify the same entry name twice. As entry names can be specified as expressions, you can easily work around this check - you will still get an error, but it would be a panic! in this case. In any case the error message will contain details of 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(b"/dev/fs /"),
        "passwd" => read_only(b"[redacted]"),
        "shells" => read_only(b"/bin/bash"),
        "ssh" => pseudo_directory! {
          "sshd_config" => read_only(b"# Empty"),
        },
    },
    "uname" => read_only(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_attr(S_IRUSR, || Ok(b"[redacted]".to_vec())),
    },
};

See [//src/storage/lib/vfs/rust:vfs/src/lib.rs] for the documentation for this macro usage.