What the tablet and the service say to each other on the Jev-backed routes (/check, /embed,
/rerank). It lives in the core, not in the guard, because both ends need it and the service
must be able to build for a Worker, which the guard's HTTP client cannot.
5use serde::{Deserialize, Serialize};
What the tablet sends the guard service: one message, which way it is going, and the age of the child it is judged for. There is no name on the wire: the service does not need one.
Optional; absent, the service judges for the youngest supported age, the strictest. An age outside the supported range does not parse, and so is refused.
The service answers a verdict, or says it could not decide. "Could not
decide" is not an Allow: the client turns it into a GuardError.
Texts to embed.
A message and the shortlist of memories to order for it.
The text of one fact, to be given a picture. A fact is what Whiskers remembers about the child, so the request carries no age and no name: the picture is chosen for the words alone.
The picture chosen for a fact, or that none of the admitted ones fits, or that it could not be decided. "Could not decide" is not "none fits": the first is tried again later, the second is an answer.
76#[cfg(test)] 77mod tests { 78 use super::*; 79 80 #[test] 81 fn an_icon_reply_names_an_admitted_icon_or_it_does_not_parse() { 82 let r: IconReply = serde_json::from_str(r#"{"Icon":"cat"}"#).unwrap(); 83 assert_eq!(r, IconReply::Icon(whiskers_icons::IconId::new("cat").unwrap())); 84 assert_eq!(serde_json::from_str::<IconReply>(r#""NoneFits""#).unwrap(), IconReply::NoneFits); 85 assert!(serde_json::from_str::<IconReply>(r#"{"Icon":"beer"}"#).is_err()); 86 assert_eq!(serde_json::to_string(&IconRequest { text: "x".into() }).unwrap(), r#"{"text":"x"}"#); 87 } 88 89 #[test] 90 fn a_request_without_an_age_is_judged_for_the_youngest() { 91 let r: CheckRequest = serde_json::from_str(r#"{"direction":"FromChild","text":"hi"}"#).unwrap(); 92 assert_eq!(r.age(), Age::YOUNGEST); 93 } 94 95 #[test] 96 fn an_age_outside_the_range_does_not_parse() { 97 assert!(serde_json::from_str::<CheckRequest>(r#"{"direction":"FromChild","age":2,"text":"hi"}"#).is_err()); 98 assert!(serde_json::from_str::<CheckRequest>(r#"{"direction":"FromChild","age":200,"text":"hi"}"#).is_err()); 99 } 100 101 #[test] 102 fn the_request_carries_the_age_and_nothing_that_could_be_a_name() { 103 let r = CheckRequest { direction: Direction::ToChild, age: Some(Age::new(6).unwrap()), text: "hi".into() }; 104 assert_eq!(serde_json::to_string(&r).unwrap(), r#"{"direction":"ToChild","age":6,"text":"hi"}"#); 105 } 106}