cynic_codegen/suggestions/
mod.rs1use strsim::jaro_winkler;
2
3pub fn guess_field<'a>(
5 candidates: impl Iterator<Item = &'a str>,
6 provided_name: &str,
7) -> Option<&'a str> {
8 let (chosen_candidate, _) = candidates
9 .map(|candidate| (candidate, jaro_winkler(candidate, provided_name)))
10 .filter(|(_, distance)| *distance > 0.6)
11 .reduce(|lhs @ (_, distance_lhs), rhs @ (_, distance_rhs)| {
12 if distance_lhs > distance_rhs {
13 lhs
14 } else {
15 rhs
16 }
17 })?;
18
19 Some(chosen_candidate)
20}
21
22pub fn format_guess(guess_field: Option<&str>) -> String {
23 match guess_field {
24 Some(v) => format!(" Did you mean `{v}`?"),
25 None => "".to_owned(),
26 }
27}
28
29pub struct FieldSuggestionError<'a> {
30 pub expected_field: &'a str,
31 pub graphql_type_name: &'a str,
32 pub suggested_field: Option<&'a str>,
33}
34
35impl std::fmt::Display for FieldSuggestionError<'_> {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 write!(
38 f,
39 "no field `{}` on the GraphQL type `{}`. {}",
40 self.expected_field,
41 self.graphql_type_name,
42 format_guess(self.suggested_field)
43 )
44 }
45}