use crate::display::RepeatDisplay;
use std::ops::Range;
use super::{Component, Separators};
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Repeat<'m> {
pub(crate) source: &'m str,
pub components: Vec<Component<'m>>,
pub range: Range<usize>,
}
impl<'m> Repeat<'m> {
pub(crate) fn new_single(source: &'m str, range: Range<usize>) -> Self {
Repeat {
source,
components: vec![Component::new_single(source, range.clone())],
range,
}
}
#[inline]
pub fn components(&self) -> impl Iterator<Item = &Component<'m>> {
self.components.iter()
}
#[inline]
pub fn display(&'m self, separators: &'m Separators) -> RepeatDisplay<'m> {
RepeatDisplay {
components: &self.components,
separators,
}
}
#[inline]
pub fn raw_value(&self) -> &'m str {
self.source
}
#[inline]
pub fn has_components(&self) -> bool {
self.components.len() > 1
}
pub fn is_empty(&self) -> bool {
self.components.is_empty() || self.components.iter().all(|c| c.is_empty())
}
pub fn component(&self, number: usize) -> Option<&Component<'m>> {
debug_assert!(number > 0, "Component numbers are 1-based");
self.components.get(number - 1)
}
}
#[cfg(test)]
mod tests {
use crate::message::Subcomponent;
use super::*;
#[test]
fn repeats_can_display_raw() {
let separators = Separators::default();
let component = Component {
source: r"foo\F\bar",
subcomponents: vec![Subcomponent {
value: r"foo\F\bar",
range: 0..1, }],
range: 0..1, };
let repeat = Repeat {
source: r"foo\F\bar~foo\F\bar",
components: vec![component.clone(), component.clone()],
range: 0..1, };
let formatted = format!("{:#}", repeat.display(&separators));
assert_eq!(formatted, r"foo\F\bar~foo\F\bar");
}
#[test]
fn repeats_can_display_decoded() {
let separators = Separators::default();
let component = Component {
source: r"foo\F\bar",
subcomponents: vec![Subcomponent {
value: r"foo\F\bar",
range: 0..1, }],
range: 0..1, };
let repeat = Repeat {
source: r"foo\F\bar~foo\F\bar",
components: vec![component.clone(), component.clone()],
range: 0..1, };
let formatted = format!("{}", repeat.display(&separators));
assert_eq!(formatted, r"foo|bar~foo|bar");
}
}