use ustar_parser::mutable_pair::MutablePair;
use ustar_parser::Rule;
use ustar_parser::{Pair, Pairs};
pub trait DumpExtractor<T: ?Sized> {
type Child;
type ChildIter: Iterator<Item = Self::Child>;
fn extract_rule_name(&self, node: &T) -> String;
fn extract_str<'a>(&self, node: &'a T) -> &'a str;
fn extract_start(&self, node: &T) -> usize;
fn extract_end(&self, node: &T) -> usize;
fn has_children(&self, node: &T) -> bool;
fn get_children(&self, node: &T) -> Self::ChildIter;
}
#[derive(Default)]
pub struct PairExtractor;
impl PairExtractor {
pub fn new() -> Self {
PairExtractor
}
}
impl<'i> DumpExtractor<Pair<'i, Rule>> for PairExtractor {
type Child = Pair<'i, Rule>;
type ChildIter = Pairs<'i, Rule>;
fn extract_rule_name(&self, node: &Pair<'i, Rule>) -> String {
format!("{:?}", node.as_rule())
}
fn extract_str<'a>(&self, node: &'a Pair<'i, Rule>) -> &'a str {
node.as_str()
}
fn extract_start(&self, node: &Pair<'i, Rule>) -> usize {
node.as_span().start()
}
fn extract_end(&self, node: &Pair<'i, Rule>) -> usize {
node.as_span().end()
}
fn has_children(&self, node: &Pair<'i, Rule>) -> bool {
node.clone().into_inner().peek().is_some()
}
fn get_children(&self, node: &Pair<'i, Rule>) -> Self::ChildIter {
node.clone().into_inner()
}
}
#[derive(Default)]
pub struct MutablePairExtractor;
impl MutablePairExtractor {
pub fn new() -> Self {
MutablePairExtractor
}
}
impl DumpExtractor<MutablePair> for MutablePairExtractor {
type Child = MutablePair; type ChildIter = std::vec::IntoIter<MutablePair>;
fn extract_rule_name(&self, node: &MutablePair) -> String {
node.rule_name().to_owned()
}
fn extract_str<'a>(&self, node: &'a MutablePair) -> &'a str {
node.as_str()
}
fn extract_start(&self, node: &MutablePair) -> usize {
node.start_pos()
}
fn extract_end(&self, node: &MutablePair) -> usize {
node.end_pos()
}
fn has_children(&self, node: &MutablePair) -> bool {
node.has_children()
}
fn get_children(&self, node: &MutablePair) -> Self::ChildIter {
node.children().to_vec().into_iter()
}
}
pub fn dump_pair(pair: &Pair<Rule>, level: usize) {
let extractor = PairExtractor::new();
let indent = " ".repeat(level);
let symbol = if extractor.has_children(pair) {
">"
} else {
"-"
};
println!(
"{}{} {} {}..{} {:?}",
indent,
symbol,
extractor.extract_rule_name(pair),
extractor.extract_start(pair),
extractor.extract_end(pair),
extractor.extract_str(pair)
);
for child in extractor.get_children(pair) {
dump_pair(&child, level + 1);
}
}
pub fn dump_mutable_pair(pair: &MutablePair, level: usize) {
let extractor = MutablePairExtractor::new();
let indent = " ".repeat(level);
let symbol = if extractor.has_children(pair) {
">"
} else {
"-"
};
println!(
"{}{} {} {}..{} {:?}",
indent,
symbol,
extractor.extract_rule_name(pair),
extractor.extract_start(pair),
extractor.extract_end(pair),
extractor.extract_str(pair)
);
for child in extractor.get_children(pair) {
dump_mutable_pair(&child, level + 1);
}
}