use async_std::path::PathBuf;
use melodium_core::*;
use melodium_macro::{check, mel_function, mel_treatment};
#[mel_treatment(
input path Stream<string>
output extension Stream<Option<string>>
output file_name Stream<Option<string>>
output file_stem Stream<Option<string>>
output parent Stream<Option<string>>
)]
pub async fn composition() {
while let Ok(paths) = path
.recv_many()
.await
.map(|values| TryInto::<Vec<string>>::try_into(values).unwrap())
{
let mut extensions = VecDeque::with_capacity(paths.len());
let mut file_names = VecDeque::with_capacity(paths.len());
let mut file_stems = VecDeque::with_capacity(paths.len());
let mut parents = VecDeque::with_capacity(paths.len());
for path in paths {
let path = PathBuf::from(path);
extensions.push_back(Value::Option(
path.extension()
.map(|s| Box::new(Value::from(s.to_string_lossy().to_string()))),
));
file_names.push_back(Value::Option(
path.file_name()
.map(|s| Box::new(Value::from(s.to_string_lossy().to_string()))),
));
file_stems.push_back(Value::Option(
path.file_stem()
.map(|s| Box::new(Value::from(s.to_string_lossy().to_string()))),
));
parents.push_back(Value::Option(
path.parent()
.map(|s| Box::new(Value::from(s.to_string_lossy().to_string()))),
));
}
if let (Err(_), Err(_), Err(_), Err(_)) = futures::join!(
extension.send_many(TransmissionValue::Other(extensions)),
file_name.send_many(TransmissionValue::Other(file_names)),
file_stem.send_many(TransmissionValue::Other(file_stems)),
parent.send_many(TransmissionValue::Other(parents))
) {
break;
}
}
}
#[mel_treatment(
input path Stream<string>
output exists Stream<bool>
)]
pub async fn exists() {
#[cfg(feature = "real")]
while let Ok(paths) = path
.recv_many()
.await
.map(|values| TryInto::<Vec<string>>::try_into(values).unwrap())
{
let mut results = Vec::with_capacity(paths.len());
for path in paths {
results.push(PathBuf::from(path).exists().await);
}
check!(exists.send_many(results.into()).await);
}
}
#[mel_treatment(
input path Stream<string>
output is_dir Stream<bool>
output is_file Stream<bool>
output length Stream<u64>
)]
pub async fn meta() {
#[cfg(feature = "real")]
while let Ok(paths) = path
.recv_many()
.await
.map(|values| TryInto::<Vec<string>>::try_into(values).unwrap())
{
let mut are_dirs = Vec::with_capacity(paths.len());
let mut are_files = Vec::with_capacity(paths.len());
let mut lengths = Vec::with_capacity(paths.len());
for path in paths {
if let Ok(metadata) = async_std::fs::metadata(path).await {
are_dirs.push(metadata.is_dir());
are_files.push(metadata.is_file());
lengths.push(metadata.len());
} else {
are_dirs.push(false);
are_files.push(false);
lengths.push(0);
}
}
if let (Err(_), Err(_), Err(_)) = futures::join!(
is_dir.send_many(are_dirs.into()),
is_file.send_many(are_files.into()),
length.send_many(lengths.into())
) {
break;
}
}
}
#[mel_function]
pub fn extension(path: string) -> Option<string> {
PathBuf::from(path)
.extension()
.map(|s| s.to_string_lossy().to_string())
}
#[mel_function]
pub fn file_name(path: string) -> Option<string> {
PathBuf::from(path)
.file_name()
.map(|s| s.to_string_lossy().to_string())
}
#[mel_function]
pub fn file_stem(path: string) -> Option<string> {
PathBuf::from(path)
.file_stem()
.map(|s| s.to_string_lossy().to_string())
}
#[mel_function]
pub fn parent(path: string) -> Option<string> {
PathBuf::from(path)
.parent()
.map(|s| s.to_string_lossy().to_string())
}