opentitanlib/util/
fs.rs

1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5use std::collections::HashMap;
6use std::io::ErrorKind;
7use std::path::Path;
8use std::sync::LazyLock;
9
10#[doc(hidden)]
11pub struct BuiltinFile {
12    pub name: &'static str,
13    pub content: &'static str,
14}
15inventory::collect!(BuiltinFile);
16
17#[doc(hidden)]
18pub use inventory::submit;
19
20/// Declare a built-in file.
21///
22/// All built-in files declared this way that gets linked will be accessible with
23/// `/__builtin__/<file name>` path when handled by parts of OT that allows built-in files.
24#[macro_export]
25macro_rules! builtin_file {
26    ($name: literal) => {
27        $crate::util::fs::builtin_file!($name, include_str!($name));
28    };
29
30    ($name: literal, $content: expr) => {
31        $crate::util::fs::submit!($crate::util::fs::BuiltinFile {
32            name: $name,
33            content: $content,
34        });
35    };
36}
37pub use crate::builtin_file;
38
39static BUILTINS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
40    inventory::iter::<BuiltinFile>()
41        .map(|x| (x.name, x.content))
42        .collect()
43});
44
45/// Equivalent to `std::fs::read_to_string`, but handle `/__builtin__` files.
46pub fn read_to_string(path: &Path) -> std::io::Result<String> {
47    if let Ok(builtin) = path.strip_prefix("/__builtin__") {
48        Ok(BUILTINS
49            .get(builtin.to_str().ok_or(ErrorKind::NotFound)?)
50            .ok_or(ErrorKind::NotFound)?
51            .to_string())
52    } else {
53        std::fs::read_to_string(path)
54    }
55}