mirror of
https://github.com/lsd-rs/lsd
synced 2024-11-10 14:24:27 +00:00
Add the first functionalities
This commit is contained in:
parent
1ca2645bc6
commit
3dc1689e65
7 changed files with 524 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
**/*.rs.bk
|
150
Cargo.lock
generated
Normal file
150
Cargo.lock
generated
Normal file
|
@ -0,0 +1,150 @@
|
|||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lsd"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
|
||||
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
|
||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
|
||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
authors = ["Peltoche <dev@halium.fr>"]
|
||||
name = "lsd"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
ansi_term = "0.11.0"
|
||||
clap = "2.32.0"
|
||||
lazy_static = "1.2.0"
|
||||
time = "0.1.40"
|
194
src/formatter.rs
Normal file
194
src/formatter.rs
Normal file
|
@ -0,0 +1,194 @@
|
|||
use ansi_term::Colour;
|
||||
use path_lister::Path;
|
||||
use std::collections::HashMap;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
use time::Timespec;
|
||||
|
||||
const HOURE: u64 = 3600; // 1 HOURE == 3600 seconds
|
||||
const DAY: u64 = HOURE * 24; // 1 DAY == 25 HOURE
|
||||
|
||||
#[derive(Hash, Debug, Eq, PartialEq, Copy, Clone)]
|
||||
pub enum PathKind {
|
||||
UnrecognizedFile,
|
||||
RecognizedFile,
|
||||
Dir,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref PathKindColor: HashMap<PathKind, (u8, u8, u8)> = {
|
||||
let mut m = HashMap::new();
|
||||
|
||||
m.insert(PathKind::UnrecognizedFile, (0xFF, 0xFF, 0x04)); // gold
|
||||
m.insert(PathKind::RecognizedFile, (0x04, 0xFF, 0x04)); // limon
|
||||
m.insert(PathKind::Dir, (0x00, 0xAF, 0xFF)); // dodgerblue
|
||||
|
||||
m
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Hash, Debug, Eq, PartialEq, Copy, Clone)]
|
||||
pub enum LastTimeModified {
|
||||
DayOld,
|
||||
HourOld,
|
||||
Older,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref LastTimeModifiedColor: HashMap<LastTimeModified, (u8, u8, u8)> = {
|
||||
let mut m = HashMap::new();
|
||||
|
||||
m.insert(LastTimeModified::HourOld, (0x2C, 0xFF, 0x2C));
|
||||
m.insert(LastTimeModified::DayOld, (0x1C, 0xFF, 0xB7));
|
||||
m.insert(LastTimeModified::Older, (0x63, 0xB1, 0x8A));
|
||||
|
||||
m
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Hash, Debug, Eq, PartialEq, Copy, Clone)]
|
||||
pub enum Elem {
|
||||
/// Link
|
||||
DeadLink,
|
||||
Link,
|
||||
|
||||
/// File Size
|
||||
FileLarge,
|
||||
FileMedium,
|
||||
FileSmall,
|
||||
|
||||
/// Random
|
||||
Report,
|
||||
User,
|
||||
Tree,
|
||||
Empty,
|
||||
Error,
|
||||
Normal,
|
||||
|
||||
/// Git
|
||||
Addition,
|
||||
Modification,
|
||||
Deletion,
|
||||
Untracked,
|
||||
Unchanged,
|
||||
}
|
||||
|
||||
pub struct Formatter {}
|
||||
|
||||
impl Formatter {
|
||||
pub fn new() -> Formatter {
|
||||
Formatter {}
|
||||
}
|
||||
|
||||
pub fn format_path(&self, content: &str, path: &Path) -> String {
|
||||
let color = match path.metadata.is_dir() {
|
||||
true => PathKindColor[&PathKind::Dir],
|
||||
false => PathKindColor[&PathKind::UnrecognizedFile],
|
||||
};
|
||||
|
||||
Colour::RGB(color.0, color.1, color.2)
|
||||
.paint(content)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn format_date(&self, path: &Path) -> String {
|
||||
let modified_time = path.metadata.modified().unwrap();
|
||||
|
||||
let now = SystemTime::now();
|
||||
|
||||
let color;
|
||||
if modified_time > now - Duration::new(HOURE, 0) {
|
||||
color = LastTimeModifiedColor[&LastTimeModified::HourOld];
|
||||
} else if modified_time > now - Duration::new(DAY, 0) {
|
||||
color = LastTimeModifiedColor[&LastTimeModified::DayOld];
|
||||
} else {
|
||||
color = LastTimeModifiedColor[&LastTimeModified::Older];
|
||||
}
|
||||
|
||||
let modified_time_since_epoch = modified_time.duration_since(UNIX_EPOCH).unwrap();
|
||||
let time = time::at(Timespec::new(
|
||||
modified_time_since_epoch.as_secs() as i64,
|
||||
modified_time_since_epoch.subsec_nanos() as i32,
|
||||
));
|
||||
|
||||
Colour::RGB(color.0, color.1, color.2)
|
||||
.paint(time.ctime().to_string())
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn format_permissions(&self, path: &Path) -> String {
|
||||
let mut res = String::with_capacity(10);
|
||||
|
||||
let mode = path.metadata.permissions().mode();
|
||||
|
||||
let read_perm = Colour::RGB(0x5f, 0xD7, 0x5F)
|
||||
.paint(String::from("r"))
|
||||
.to_string();
|
||||
let write_perm = Colour::RGB(0xD7, 0xD7, 0x87)
|
||||
.paint(String::from("w"))
|
||||
.to_string();
|
||||
let exec_perm = Colour::RGB(0xCD, 0x3A, 0x3A)
|
||||
.paint(String::from("x"))
|
||||
.to_string();
|
||||
let no_access = Colour::RGB(0xD7, 0x89, 0x89)
|
||||
.paint(String::from("-"))
|
||||
.to_string();
|
||||
|
||||
// User Read Permisssions
|
||||
match mode & 0o400 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + read_perm.as_str(),
|
||||
}
|
||||
|
||||
// User Write Permisssions
|
||||
match mode & 0o200 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + write_perm.as_str(),
|
||||
}
|
||||
|
||||
// User Exec Permisssions
|
||||
match mode & 0o100 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + exec_perm.as_str(),
|
||||
}
|
||||
|
||||
// Group Read Permisssions
|
||||
match mode & 0o040 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + read_perm.as_str(),
|
||||
}
|
||||
|
||||
// Group Write Permisssions
|
||||
match mode & 0o020 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + write_perm.as_str(),
|
||||
}
|
||||
|
||||
// Group Exec Permisssions
|
||||
match mode & 0o010 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + exec_perm.as_str(),
|
||||
}
|
||||
|
||||
// Other Read Permisssions
|
||||
match mode & 0o040 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + read_perm.as_str(),
|
||||
}
|
||||
|
||||
// Other Write Permisssions
|
||||
match mode & 0o020 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + write_perm.as_str(),
|
||||
}
|
||||
|
||||
// Other Exec Permisssions
|
||||
match mode & 0o010 {
|
||||
0 => res = res + no_access.as_str(),
|
||||
_ => res = res + exec_perm.as_str(),
|
||||
}
|
||||
|
||||
res.to_string()
|
||||
}
|
||||
}
|
40
src/main.rs
Normal file
40
src/main.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
extern crate clap;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate ansi_term;
|
||||
extern crate time;
|
||||
|
||||
mod formatter;
|
||||
mod path_lister;
|
||||
mod presenter;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use path_lister::PathLister;
|
||||
use presenter::Presenter;
|
||||
|
||||
pub struct Options {
|
||||
pub display_long: bool,
|
||||
pub display_all: bool,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let matches = App::new("lsd")
|
||||
.about("A ls comment with a lot of pretty colors and some other stuff.")
|
||||
.arg(Arg::with_name("FILE").multiple(true).default_value("."))
|
||||
.arg(Arg::with_name("long").short("l"))
|
||||
.arg(Arg::with_name("all").short("a"))
|
||||
.get_matches();
|
||||
|
||||
let options = Options {
|
||||
display_long: matches.is_present("long"),
|
||||
display_all: matches.is_present("all"),
|
||||
};
|
||||
|
||||
let inputs: Vec<&str> = matches.values_of("FILE").unwrap().collect();
|
||||
|
||||
let path_lister = PathLister::new(&options);
|
||||
|
||||
let presenter = Presenter::new(&options);
|
||||
|
||||
presenter.print(path_lister.list_paths_to_print(inputs));
|
||||
}
|
80
src/path_lister.rs
Normal file
80
src/path_lister.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
use std::fs::Metadata;
|
||||
use std::io::ErrorKind;
|
||||
use std::path::{self, PathBuf};
|
||||
use Options;
|
||||
|
||||
pub struct Path {
|
||||
pub path: PathBuf,
|
||||
pub metadata: Metadata,
|
||||
}
|
||||
|
||||
pub struct PathLister<'a> {
|
||||
options: &'a Options,
|
||||
}
|
||||
|
||||
impl<'a> PathLister<'a> {
|
||||
pub fn new(options: &'a Options) -> PathLister<'a> {
|
||||
PathLister { options: options }
|
||||
}
|
||||
|
||||
pub fn list_paths_to_print(&self, inputs: Vec<&'a str>) -> Vec<Path> {
|
||||
let mut res = Vec::new();
|
||||
|
||||
for input in inputs.iter() {
|
||||
let path = path::Path::new(input);
|
||||
|
||||
let res_meta = path.metadata();
|
||||
|
||||
if let Err(err) = res_meta {
|
||||
match err.kind() {
|
||||
ErrorKind::NotFound => println!("Specified path \"{}\" doesn't exists.", input),
|
||||
ErrorKind::PermissionDenied => {
|
||||
println!("Cannot open \"{}\": Permission denied", input)
|
||||
}
|
||||
_ => println!("Cannot open \"{}\": {}", input, err),
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(meta) = res_meta {
|
||||
let file_type = meta.file_type();
|
||||
|
||||
if file_type.is_file() {
|
||||
self.add_path_to_list(&mut res, path.to_path_buf(), meta);
|
||||
continue;
|
||||
}
|
||||
|
||||
if file_type.is_dir() {
|
||||
self.read_paths_from_dir(&mut res, path.to_path_buf());
|
||||
continue;
|
||||
}
|
||||
|
||||
if file_type.is_symlink() {}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn read_paths_from_dir(&self, path_list: &mut Vec<Path>, path: PathBuf) {
|
||||
for entry in path.read_dir().expect("read_dir call failed") {
|
||||
if let Ok(entry) = entry {
|
||||
self.add_path_to_list(path_list, entry.path(), entry.metadata().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_path_to_list(&self, path_list: &mut Vec<Path>, path: PathBuf, meta: Metadata) {
|
||||
// Skip the hidden files if the 'display_all' option is not set.
|
||||
if path.file_name().unwrap().to_str().unwrap().starts_with(".") && !self.options.display_all
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
path_list.push(Path {
|
||||
path: path.to_path_buf(),
|
||||
metadata: meta,
|
||||
});
|
||||
}
|
||||
}
|
48
src/presenter.rs
Normal file
48
src/presenter.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use formatter::*;
|
||||
use path_lister::Path;
|
||||
use Options;
|
||||
|
||||
pub struct Presenter<'a> {
|
||||
formatter: Formatter,
|
||||
options: &'a Options,
|
||||
}
|
||||
|
||||
impl<'a> Presenter<'a> {
|
||||
pub fn new(options: &'a Options) -> Presenter<'a> {
|
||||
Presenter {
|
||||
options: options,
|
||||
formatter: Formatter::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print(&self, paths: Vec<Path>) {
|
||||
if self.options.display_long {
|
||||
self.print_long(&paths);
|
||||
return;
|
||||
}
|
||||
|
||||
self.print_simple(&paths)
|
||||
}
|
||||
|
||||
fn print_long(&self, paths: &Vec<Path>) {
|
||||
for path in paths {
|
||||
print!(
|
||||
" {} {} {}\n",
|
||||
self.formatter.format_permissions(path),
|
||||
self.formatter.format_date(path),
|
||||
self.formatter
|
||||
.format_path(path.path.file_name().unwrap().to_str().unwrap(), &path)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn print_simple(&self, paths: &Vec<Path>) {
|
||||
for path in paths {
|
||||
print!(
|
||||
"{}\n",
|
||||
self.formatter
|
||||
.format_path(path.path.file_name().unwrap().to_str().unwrap(), &path)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue