Files
shed/src/libsh/utils.rs

74 lines
1.5 KiB
Rust

use std::collections::VecDeque;
use crate::parse::lex::{Span, Tk};
use crate::parse::{Redir, RedirType};
use crate::prelude::*;
pub trait VecDequeExt<T> {
fn to_vec(self) -> Vec<T>;
}
pub trait TkVecUtils<Tk> {
fn get_span(&self) -> Option<Span>;
fn debug_tokens(&self);
}
pub trait RedirVecUtils<Redir> {
/// Splits the vector of redirections into two vectors
///
/// One vector contains input redirs, the other contains output redirs
fn split_by_channel(self) -> (Vec<Redir>,Vec<Redir>);
}
impl<T> VecDequeExt<T> for VecDeque<T> {
fn to_vec(self) -> Vec<T> {
self.into_iter().collect::<Vec<T>>()
}
}
impl<'t> TkVecUtils<Tk<'t>> for Vec<Tk<'t>> {
fn get_span(&self) -> Option<Span<'t>> {
if let Some(first_tk) = self.first() {
if let Some(last_tk) = self.last() {
Some(
Span::new(
first_tk.span.start..last_tk.span.end,
first_tk.source()
)
)
} else {
None
}
} else {
None
}
}
fn debug_tokens(&self) {
for token in self {
flog!(DEBUG, "token: {}",token)
}
}
}
impl RedirVecUtils<Redir> for Vec<Redir> {
fn split_by_channel(self) -> (Vec<Redir>,Vec<Redir>) {
let mut input = vec![];
let mut output = vec![];
for redir in self {
match redir.class {
RedirType::Input => input.push(redir),
RedirType::Pipe => {
match redir.io_mode.tgt_fd() {
STDIN_FILENO => input.push(redir),
STDOUT_FILENO |
STDERR_FILENO => output.push(redir),
_ => unreachable!()
}
}
_ => output.push(redir)
}
}
(input,output)
}
}