apollo_federation/connectors/runtime/
mapping.rs1use std::collections::HashMap;
4
5use itertools::Itertools;
6use serde::Deserialize;
7use serde::Serialize;
8
9use crate::connectors::ApplyToError;
10use crate::connectors::ProblemLocation;
11
12#[derive(Clone, Debug, Serialize, Deserialize)]
14pub struct Problem {
15 pub message: String,
16 pub path: String,
17 pub count: usize,
18 pub location: ProblemLocation,
19}
20
21pub fn aggregate_apply_to_errors(
23 errors: Vec<ApplyToError>,
24 location: ProblemLocation,
25) -> impl Iterator<Item = Problem> {
26 errors
27 .into_iter()
28 .fold(
29 HashMap::default(),
30 |mut acc: HashMap<(String, String), usize>, err| {
31 let path = err
32 .path()
33 .iter()
34 .map(|p| match p.as_u64() {
35 Some(_) => "@", None => p.as_str().unwrap_or_default(),
37 })
38 .join(".");
39
40 acc.entry((err.message().to_string(), path))
41 .and_modify(|c| *c += 1)
42 .or_insert(1);
43 acc
44 },
45 )
46 .into_iter()
47 .map(move |((message, path), count)| Problem {
48 message,
49 path,
50 count,
51 location,
52 })
53}
54
55pub fn aggregate_apply_to_errors_with_problem_locations(
57 errors: Vec<(ProblemLocation, ApplyToError)>,
58) -> impl Iterator<Item = Problem> {
59 errors
60 .into_iter()
61 .fold(
62 HashMap::new(),
63 |mut acc: HashMap<ProblemLocation, Vec<ApplyToError>>, (loc, err)| {
64 acc.entry(loc).or_default().push(err);
65 acc
66 },
67 )
68 .into_iter()
69 .flat_map(|(location, errors)| aggregate_apply_to_errors(errors, location))
70}