mirror of
https://github.com/RGBCube/embd-rs
synced 2025-07-26 21:17:44 +00:00
Todo dirs
This commit is contained in:
parent
d262e42422
commit
c031e19e7f
15 changed files with 371 additions and 179 deletions
9
.gitignore
vendored
9
.gitignore
vendored
|
@ -1,11 +1,14 @@
|
||||||
*
|
*
|
||||||
|
|
||||||
!src/
|
!embed/
|
||||||
|
!embed/src/
|
||||||
|
|
||||||
|
!macros/
|
||||||
|
!macros/src/
|
||||||
|
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
|
||||||
!Cargo.lock
|
!*.lock
|
||||||
|
|
||||||
!*.md
|
!*.md
|
||||||
!*.rs
|
!*.rs
|
||||||
!*.toml
|
!*.toml
|
||||||
|
|
38
Cargo.lock
generated
38
Cargo.lock
generated
|
@ -6,46 +6,46 @@ version = 3
|
||||||
name = "embed"
|
name = "embed"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"include_dir",
|
"embed_macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "include_dir"
|
name = "embed_macros"
|
||||||
version = "0.7.3"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"include_dir_macros",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "include_dir_macros"
|
|
||||||
version = "0.7.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
"quote",
|
||||||
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.70"
|
version = "1.0.73"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92d27c2c202598d05175a6dd3af46824b7f747f8d8e9b14c623f19fa5069735d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
|
|
15
Cargo.toml
15
Cargo.toml
|
@ -1,13 +1,2 @@
|
||||||
[package]
|
[workspace]
|
||||||
name = "embed"
|
members = [ "embed", "macros" ]
|
||||||
description = "Read files or directories from the filesystem at runtime on debug, embed on release."
|
|
||||||
repository = "https://github.com/RGBCube/embed-rs"
|
|
||||||
license = "MIT"
|
|
||||||
keywords = [ "embedding", "files", "debug-optimization", "bundling" ]
|
|
||||||
cateories = [ "filesystem" ]
|
|
||||||
authors = [ "RGBCube" ]
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
include_dir = { version = "^0.7", features = [ "metadata" ] }
|
|
||||||
|
|
|
@ -4,13 +4,16 @@ A super simple file and directory embedding crate,
|
||||||
that loads files from the filesystem in debug mode,
|
that loads files from the filesystem in debug mode,
|
||||||
allowing for quick edit-and-test cycles without compilation.
|
allowing for quick edit-and-test cycles without compilation.
|
||||||
|
|
||||||
On release mode it falls back to `include_str!`, `include_bytes!` and `include_dir!`.
|
On release mode it falls back to `include_str!`, `include_bytes!`
|
||||||
|
and our own custom `include_dir!` implementation.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
let contents: Cow<'_, str> = embed::string!("path/to/file.txt");
|
let contents: Cow<'_, str> = embed::string!("path/to/file.txt");
|
||||||
let bytes: Cow<'_, [u8]> = embed::bytes!("path/to/image.png");
|
let bytes: Cow<'_, [u8]> = embed::bytes!("path/to/image.png");
|
||||||
|
|
||||||
|
let dir: embed::Dir = embed::dir!("path/to");
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
53
embed/Cargo.lock
generated
Normal file
53
embed/Cargo.lock
generated
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embed"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"include_dir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "include_dir"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e"
|
||||||
|
dependencies = [
|
||||||
|
"include_dir_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "include_dir_macros"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.70"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
13
embed/Cargo.toml
Normal file
13
embed/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "embed"
|
||||||
|
description = "Read files or directories from the filesystem at runtime on debug, embed on release."
|
||||||
|
repository = "https://github.com/RGBCube/embed-rs"
|
||||||
|
license = "MIT"
|
||||||
|
keywords = [ "embedding", "files", "debug-optimization", "bundling" ]
|
||||||
|
categories = [ "filesystem" ]
|
||||||
|
authors = [ "RGBCube" ]
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
embed_macros = { path = "../macros" }
|
43
embed/README.md
Normal file
43
embed/README.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# embed-rs
|
||||||
|
|
||||||
|
A super simple file and directory embedding crate,
|
||||||
|
that loads files from the filesystem in debug mode,
|
||||||
|
allowing for quick edit-and-test cycles without compilation.
|
||||||
|
|
||||||
|
On release mode it falls back to `include_str!`, `include_bytes!`
|
||||||
|
and our own custom `include_dir!` implementation.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```rs
|
||||||
|
let contents: Cow<'_, str> = embed::string!("path/to/file.txt");
|
||||||
|
let bytes: Cow<'_, [u8]> = embed::bytes!("path/to/image.png");
|
||||||
|
|
||||||
|
let dir: embed::Dir = embed::dir!("path/to");
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023-present RGBCube
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
```
|
86
embed/src/dir.rs
Normal file
86
embed/src/dir.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
use std::{
|
||||||
|
fs::{
|
||||||
|
self,
|
||||||
|
},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub enum DirEntry {
|
||||||
|
Dir(Dir),
|
||||||
|
File(File),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Dir {
|
||||||
|
pub children: Vec<DirEntry>,
|
||||||
|
pub path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dir {
|
||||||
|
pub fn flatten(self) -> Vec<File> {
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
|
for child in self.children {
|
||||||
|
match child {
|
||||||
|
DirEntry::File(file) => entries.push(file),
|
||||||
|
DirEntry::Dir(dir) => entries.append(&mut dir.flatten()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct File {
|
||||||
|
pub content: Vec<u8>,
|
||||||
|
pub path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(path: &PathBuf) -> Vec<DirEntry> {
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
|
for entry in fs::read_dir(path).expect("Failed to list directory contents") {
|
||||||
|
let entry = entry.expect("Failed to read entry");
|
||||||
|
|
||||||
|
let filetype = entry.file_type().expect("Failed to read entry filetype");
|
||||||
|
let path = entry
|
||||||
|
.path()
|
||||||
|
.canonicalize()
|
||||||
|
.expect("Failed to get the canonical path of the DirEntry");
|
||||||
|
|
||||||
|
if filetype.is_dir() {
|
||||||
|
let children = read_dir(&path);
|
||||||
|
|
||||||
|
entries.push(DirEntry::Dir(Dir { children, path }))
|
||||||
|
} else if filetype.is_file() {
|
||||||
|
let content = fs::read(&path).expect("Failed to read file contents");
|
||||||
|
|
||||||
|
entries.push(DirEntry::File(File { content, path }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __include_dir(path: &str) -> Dir {
|
||||||
|
let path = PathBuf::from(path)
|
||||||
|
.canonicalize()
|
||||||
|
.expect("Failed to get the canonical path of the DirEntry");
|
||||||
|
|
||||||
|
let children = read_dir(&path);
|
||||||
|
|
||||||
|
Dir { children, path }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! dir {
|
||||||
|
($path:literal) => {{
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
::embed::__include_dir($path)
|
||||||
|
}
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
{
|
||||||
|
::embed_macros::__include_dir!($path)
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
5
embed/src/lib.rs
Normal file
5
embed/src/lib.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
mod dir;
|
||||||
|
pub use dir::*;
|
||||||
|
|
||||||
|
mod file;
|
||||||
|
pub use file::*;
|
17
macros/Cargo.toml
Normal file
17
macros/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "embed_macros"
|
||||||
|
description = "Read files or directories from the filesystem at runtime on debug, embed on release."
|
||||||
|
repository = "https://github.com/RGBCube/embed-rs"
|
||||||
|
license = "MIT"
|
||||||
|
keywords = [ "embedding", "files", "debug-optimization", "bundling" ]
|
||||||
|
categories = [ "filesystem" ]
|
||||||
|
authors = [ "RGBCube" ]
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc_macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
quote = "1"
|
||||||
|
syn = "2"
|
43
macros/README.md
Normal file
43
macros/README.md
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# embed-rs
|
||||||
|
|
||||||
|
A super simple file and directory embedding crate,
|
||||||
|
that loads files from the filesystem in debug mode,
|
||||||
|
allowing for quick edit-and-test cycles without compilation.
|
||||||
|
|
||||||
|
On release mode it falls back to `include_str!`, `include_bytes!`
|
||||||
|
and our own custom `include_dir!` implementation.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```rs
|
||||||
|
let contents: Cow<'_, str> = embed::string!("path/to/file.txt");
|
||||||
|
let bytes: Cow<'_, [u8]> = embed::bytes!("path/to/image.png");
|
||||||
|
|
||||||
|
let dir: embed::Dir = embed::dir!("path/to");
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023-present RGBCube
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
```
|
80
macros/src/lib.rs
Normal file
80
macros/src/lib.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::{
|
||||||
|
parse_macro_input,
|
||||||
|
LitStr,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn __include_dir(tokens: TokenStream) -> TokenStream {
|
||||||
|
let path = parse_macro_input!(tokens as LitStr).value();
|
||||||
|
|
||||||
|
let path = PathBuf::from(path)
|
||||||
|
.canonicalize()
|
||||||
|
.expect("Failed to get the canonical path of the DirEntry");
|
||||||
|
|
||||||
|
let path_str = path
|
||||||
|
.to_str()
|
||||||
|
.expect("Failed to get the string representation of PathBuf");
|
||||||
|
|
||||||
|
let children = read_dir(&path);
|
||||||
|
let children_tokens = quote! {
|
||||||
|
vec![#(#children),*]
|
||||||
|
};
|
||||||
|
|
||||||
|
TokenStream::from(quote! {
|
||||||
|
::embed::Dir {
|
||||||
|
children: #children_tokens,
|
||||||
|
path: ::std::path::PathBuf::from(#path_str),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(path: &PathBuf) -> Vec<TokenStream> {
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
|
for entry in fs::read_dir(path).expect("Failed to list directory contents") {
|
||||||
|
let entry = entry.expect("Failed to read entry");
|
||||||
|
|
||||||
|
let path = entry
|
||||||
|
.path()
|
||||||
|
.canonicalize()
|
||||||
|
.expect("Failed to get the canonical path of the DirEntry");
|
||||||
|
|
||||||
|
let path_str = path
|
||||||
|
.to_str()
|
||||||
|
.expect("Failed to get the string representation of PathBuf");
|
||||||
|
|
||||||
|
let filetype = fs::metadata(path)
|
||||||
|
.expect("Failed to get file metadata")
|
||||||
|
.file_type();
|
||||||
|
|
||||||
|
if filetype.is_dir() {
|
||||||
|
let children = read_dir(&path);
|
||||||
|
let children_tokens = quote! {
|
||||||
|
vec![#(#children),*]
|
||||||
|
};
|
||||||
|
|
||||||
|
entries.push(quote! {
|
||||||
|
::embed::DirEntry(::embed::Dir {
|
||||||
|
children: #children_tokens,
|
||||||
|
path: ::std::path::PathBuf::from(#path_str),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} else if filetype.is_file() {
|
||||||
|
entries.push(quote! {
|
||||||
|
::embed::DirEntry(::embed::File {
|
||||||
|
content: ::include_bytes!(#path_str),
|
||||||
|
path: ::std::path::PathBuf::from(#path_str),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries
|
||||||
|
}
|
138
src/dir.rs
138
src/dir.rs
|
@ -1,138 +0,0 @@
|
||||||
use std::{
|
|
||||||
fs,
|
|
||||||
path::PathBuf,
|
|
||||||
time::SystemTime,
|
|
||||||
};
|
|
||||||
|
|
||||||
use include_dir::{
|
|
||||||
Dir,
|
|
||||||
DirEntry,
|
|
||||||
File,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn read_dir(dir: &PathBuf) -> Vec<PathBuf> {
|
|
||||||
if !dir.is_dir() {
|
|
||||||
panic!("embed: {path} is not a directory", path = dir.display());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut paths = Vec::new();
|
|
||||||
|
|
||||||
for entry in dir.read_dir().unwrap_or_else(|error| {
|
|
||||||
panic!(
|
|
||||||
"embed: failed to read directory {dir}: {error}",
|
|
||||||
dir = dir.display()
|
|
||||||
)
|
|
||||||
}) {
|
|
||||||
paths.push(
|
|
||||||
entry
|
|
||||||
.unwrap_or_else(|error| panic!("embed: failed to resolve entry: {error}"))
|
|
||||||
.path(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
paths.sort();
|
|
||||||
paths
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_to_entry<'a>(path: &'a PathBuf) -> DirEntry<'a> {
|
|
||||||
let abs = path.canonicalize().unwrap_or_else(|error| {
|
|
||||||
panic!(
|
|
||||||
"embed: failed to resolve path {path}: {error}",
|
|
||||||
path = path.display()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
let contents = fs::read(&path).unwrap_or_else(|error| {
|
|
||||||
panic!(
|
|
||||||
"embed: failed to read file {path}: {error}",
|
|
||||||
path = path.display()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut entry = File::new(abs.to_str().unwrap(), contents.as_slice());
|
|
||||||
|
|
||||||
if let Ok(metadata) = path.metadata() {
|
|
||||||
entry = entry.with_metadata(include_dir::Metadata::new(
|
|
||||||
metadata
|
|
||||||
.accessed()
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!("embed: failed to read metadata.accessed of {metadata:?}: {error}");
|
|
||||||
})
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!("embed: failed to calculate time difference: {error}")
|
|
||||||
}),
|
|
||||||
metadata
|
|
||||||
.created()
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!("embed: failed to read metadata.created of {metadata:?}: {error}");
|
|
||||||
})
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!("embed: failed to calculate time difference: {error}")
|
|
||||||
}),
|
|
||||||
metadata
|
|
||||||
.modified()
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!("embed: failed to read metadata.modified of {metadata:?}: {error}");
|
|
||||||
})
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
|
||||||
.unwrap_or_else(|error| {
|
|
||||||
panic!("embed: failed to calculate time difference: {error}")
|
|
||||||
}),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
DirEntry::File(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dir_to_entries<'a>(root: &'a PathBuf, path: &'a PathBuf) -> Vec<DirEntry<'a>> {
|
|
||||||
let mut entries = Vec::new();
|
|
||||||
|
|
||||||
for child in read_dir(path) {
|
|
||||||
if child.is_dir() {
|
|
||||||
entries.push(DirEntry::Dir(Dir::new(
|
|
||||||
root.as_os_str().to_str().unwrap_or_else(|| {
|
|
||||||
panic!(
|
|
||||||
"embed: failed to convert {lossy} to &str as it was not valid unicode",
|
|
||||||
lossy = root.to_string_lossy()
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
&dir_to_entries(root, &child),
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
else if child.is_file() {
|
|
||||||
entries.push(file_to_entry(&child))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
panic!(
|
|
||||||
"{child} is neither a file or directory",
|
|
||||||
child = child.display()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entries
|
|
||||||
}
|
|
||||||
|
|
||||||
fn include_dir<'a>(path_str: &'a str) -> Dir<'a> {
|
|
||||||
let path = PathBuf::from(path_str);
|
|
||||||
|
|
||||||
let entries = dir_to_entries(&path, &path);
|
|
||||||
|
|
||||||
Dir::new(path_str, entries.as_slice())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! dir {
|
|
||||||
($path:literal) => {{
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
{
|
|
||||||
include_dir($path)
|
|
||||||
}
|
|
||||||
#[cfg(not(debug_assertions))]
|
|
||||||
{
|
|
||||||
include_dir!($path)
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
// mod dir;
|
|
||||||
// pub use dir::*;
|
|
||||||
|
|
||||||
mod file;
|
|
||||||
pub use file::*;
|
|
Loading…
Add table
Add a link
Reference in a new issue