use crate::element::iterators::{AnnotationsIntoIter, SymbolsIterator};
use crate::ion_data::{IonDataHash, IonDataOrd};
use crate::Symbol;
use std::cmp::Ordering;
use std::hash::Hasher;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Annotations {
symbols: Vec<Symbol>,
}
impl Annotations {
pub(crate) fn new(symbols: Vec<Symbol>) -> Self {
Annotations { symbols }
}
pub fn empty() -> Self {
Annotations {
symbols: Vec::new(),
}
}
pub fn iter(&self) -> SymbolsIterator<'_> {
SymbolsIterator::new(self.symbols.as_slice())
}
pub fn len(&self) -> usize {
self.symbols.len()
}
pub fn is_empty(&self) -> bool {
self.symbols.len() == 0
}
pub fn contains<S: AsRef<str>>(&self, query: S) -> bool {
let query: &str = query.as_ref();
self.iter().any(|symbol| symbol.text() == Some(query))
}
pub fn first(&self) -> Option<&str> {
self.iter().next().and_then(|a| a.text())
}
}
impl AsRef<[Symbol]> for Annotations {
fn as_ref(&self) -> &[Symbol] {
self.symbols.as_slice()
}
}
impl From<Vec<Symbol>> for Annotations {
fn from(value: Vec<Symbol>) -> Self {
Annotations::new(value)
}
}
impl<S: Into<Symbol>> FromIterator<S> for Annotations {
fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
iter.into_annotations()
}
}
impl<'a> IntoIterator for &'a Annotations {
type Item = &'a Symbol;
type IntoIter = SymbolsIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
SymbolsIterator::new(self.symbols.as_slice())
}
}
impl IntoIterator for Annotations {
type Item = Symbol;
type IntoIter = AnnotationsIntoIter;
fn into_iter(self) -> Self::IntoIter {
AnnotationsIntoIter::new(self.symbols.into_iter())
}
}
impl IonDataOrd for Annotations {
fn ion_cmp(&self, other: &Self) -> Ordering {
self.symbols.ion_cmp(&other.symbols)
}
}
impl IonDataHash for Annotations {
fn ion_data_hash<H: Hasher>(&self, state: &mut H) {
self.symbols.ion_data_hash(state)
}
}
pub trait IntoAnnotations {
fn into_annotations(self) -> Annotations;
}
impl<S, I> IntoAnnotations for I
where
S: Into<Symbol>,
I: IntoIterator<Item = S>,
{
fn into_annotations(self) -> Annotations {
let symbols: Vec<Symbol> = self.into_iter().map(|a| a.into()).collect();
Annotations::new(symbols)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_into_iter() {
let expected = vec!["a", "b", "c"].into_annotations();
let collect: Annotations = expected.clone().into_iter().collect();
assert_eq!(expected, collect);
}
#[test]
fn test_from_vec() {
let expected = vec!["d", "e", "f"].into_annotations();
let symbols: Vec<_> = expected.clone().into_iter().collect();
let from: Annotations = symbols.into();
assert_eq!(expected, from);
}
}