use super::{
api::{AnalysisPhase, Api, ApiDetail},
convert_error::{ConvertErrorWithContext, ErrorContext},
ConvertError,
};
use crate::types::{Namespace, QualifiedName};
use std::collections::HashSet;
pub(crate) fn report_any_error<F, T>(
ns: &Namespace,
apis: &mut Vec<Api<impl AnalysisPhase>>,
fun: F,
) -> Option<T>
where
F: FnOnce() -> Result<T, ConvertErrorWithContext>,
{
match fun() {
Ok(result) => Some(result),
Err(ConvertErrorWithContext(err, None)) => {
eprintln!("Ignored item: {}", err);
None
}
Err(ConvertErrorWithContext(err, Some(ctx))) => {
eprintln!("Ignored item {}: {}", ctx.to_string(), err);
push_ignored_item(ns, ctx, err, apis);
None
}
}
}
pub(crate) fn convert_apis<F, A, B>(in_apis: Vec<Api<A>>, out_apis: &mut Vec<Api<B>>, mut fun: F)
where
F: FnMut(Api<A>) -> Result<Option<Api<B>>, ConvertErrorWithContext>,
A: AnalysisPhase,
B: AnalysisPhase,
{
out_apis.extend(in_apis.into_iter().filter_map(|api| {
let tn = api.name();
match fun(api) {
Ok(opt) => opt,
Err(ConvertErrorWithContext(err, None)) => {
eprintln!("Ignored {}: {}", tn.to_string(), err);
None
}
Err(ConvertErrorWithContext(err, Some(ctx))) => {
eprintln!("Ignored {}: {}", tn.to_string(), err);
Some(ignored_item(tn.get_namespace(), ctx, err))
}
}
}))
}
pub(crate) fn convert_item_apis<F, A, B>(
in_apis: Vec<Api<A>>,
out_apis: &mut Vec<Api<B>>,
mut fun: F,
) where
F: FnMut(Api<A>) -> Result<Option<Api<B>>, ConvertError>,
A: AnalysisPhase,
B: AnalysisPhase,
{
convert_apis(in_apis, out_apis, |api| {
let id = api.name().get_final_ident();
fun(api).map_err(|e| ConvertErrorWithContext(e, Some(ErrorContext::Item(id))))
})
}
fn ignored_item<A: AnalysisPhase>(ns: &Namespace, ctx: ErrorContext, err: ConvertError) -> Api<A> {
Api {
name: QualifiedName::new(ns, ctx.get_id().clone()),
cpp_name: None,
deps: HashSet::new(),
detail: ApiDetail::IgnoredItem { err, ctx },
}
}
fn push_ignored_item(
ns: &Namespace,
ctx: ErrorContext,
err: ConvertError,
apis: &mut Vec<Api<impl AnalysisPhase>>,
) {
apis.push(ignored_item(ns, ctx, err));
}