use super::attr::{AttrChar, AttrField};
use crate::semantics::Field;
pub trait Strip {
type Output;
#[must_use]
fn strip(self) -> Self::Output;
}
impl Strip for AttrChar {
type Output = char;
fn strip(self) -> char {
self.value
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct Iter<I>(I);
impl<I> Iterator for Iter<I>
where
I: Iterator,
<I as Iterator>::Item: Strip,
{
type Item = <<I as Iterator>::Item as Strip>::Output;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(Strip::strip)
}
}
impl<I> Strip for I
where
I: Iterator,
<I as Iterator>::Item: Strip,
{
type Output = Iter<I>;
fn strip(self) -> Iter<I> {
Iter(self)
}
}
impl Strip for AttrField {
type Output = Field;
fn strip(self) -> Field {
let value = self.chars.into_iter().strip().collect();
let origin = self.origin;
Field { value, origin }
}
}
impl Strip for &AttrField {
type Output = Field;
fn strip(self) -> Field {
let value = self.chars.iter().copied().strip().collect();
let origin = self.origin.clone();
Field { value, origin }
}
}
#[cfg(test)]
mod tests {
use super::super::attr::Origin;
use super::*;
use crate::source::Location;
#[test]
fn attr_field_strip() {
let origin = Location::dummy("foo");
let field = AttrField {
chars: vec![
AttrChar {
value: 'a',
origin: Origin::Literal,
is_quoted: true,
is_quoting: false,
},
AttrChar {
value: 'x',
origin: Origin::Literal,
is_quoted: false,
is_quoting: true,
},
],
origin: origin.clone(),
};
let stripped = (&field).strip();
let expected = Field {
value: "ax".to_string(),
origin,
};
assert_eq!(stripped, expected);
let stripped = field.strip();
assert_eq!(stripped, expected);
}
}