use indexmap::set::IndexSet as HashSet;
use crate::{
conversion::{api::ApiName, convert_error::ErrorContext, ConvertErrorFromCpp},
types::QualifiedName,
};
use super::api::{AnalysisPhase, Api};
#[derive(Debug)]
pub(crate) struct ApiVec<P: AnalysisPhase> {
apis: Vec<Api<P>>,
names: HashSet<QualifiedName>,
}
impl<P: AnalysisPhase> ApiVec<P> {
pub(crate) fn push(&mut self, api: Api<P>) {
let name = api.name();
let already_contains = self.already_contains(name);
if already_contains {
if api.discard_duplicates() {
log::info!("Discarding duplicate API for {}", name);
} else {
log::info!(
"Duplicate API for {} - removing all of them and replacing with an IgnoredItem.",
name
);
self.retain(|api| api.name() != name);
self.push(Api::IgnoredItem {
name: ApiName::new_from_qualified_name(name.clone()),
err: ConvertErrorFromCpp::DuplicateItemsFoundInParsing,
ctx: Some(ErrorContext::new_for_item(name.get_final_ident())),
})
}
} else {
self.names.insert(name.clone());
self.apis.push(api)
}
}
fn already_contains(&self, name: &QualifiedName) -> bool {
self.names.contains(name)
}
pub(crate) fn new() -> Self {
Self::default()
}
pub(crate) fn append(&mut self, more: &mut ApiVec<P>) {
self.extend(more.apis.drain(..))
}
pub(crate) fn extend(&mut self, it: impl Iterator<Item = Api<P>>) {
for api in it {
self.push(api)
}
}
pub(crate) fn iter(&self) -> impl Iterator<Item = &Api<P>> {
self.apis.iter()
}
pub(crate) fn into_iter(self) -> impl Iterator<Item = Api<P>> {
self.apis.into_iter()
}
pub(crate) fn is_empty(&self) -> bool {
self.apis.is_empty()
}
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&Api<P>) -> bool,
{
self.apis.retain(f);
self.names.clear();
self.names
.extend(self.apis.iter().map(|api| api.name()).cloned());
}
}
impl<P: AnalysisPhase> Default for ApiVec<P> {
fn default() -> Self {
Self {
apis: Default::default(),
names: Default::default(),
}
}
}
impl<P: AnalysisPhase> FromIterator<Api<P>> for ApiVec<P> {
fn from_iter<I: IntoIterator<Item = Api<P>>>(iter: I) -> Self {
let mut this = ApiVec::new();
for i in iter {
this.push(i);
}
this
}
}