icon.rsannotatedicon.rssource47 lines · 1.9 KB · raw
1//! `/icon`: the picture for one fact.
2
3use ::log::{debug, info, warn};
4use whiskers_core::wire::{IconReply, IconRequest};
5use whiskers_ports::{Clock, HasClock, HasEmbedder, HasIcons, HasJudge, pick_icon};
6
7use super::{Route, sealed};
8use crate::Response;
9
10/// `POST /icon`: the best admitted picture for the words of a fact, or that none fits. Needs the embedder (to
11/// shortlist by meaning), the judge (to choose), the cache of the picture names' vectors and the clock.
12pub struct PickIcon;
13
14impl sealed::Sealed for PickIcon {}
15
16impl<C: HasEmbedder + HasJudge + HasIcons + HasClock> Route<C> for PickIcon {
17    const PATHS: &'static [&'static str] = &["/icon"];
18    async fn answer(&self, adapter: &C, _: &str, body: &str) -> Response {
19        let reply = match serde_json::from_str::<IconRequest>(body) {
20            Ok(req) => {
21                debug!("/icon: a fact of {} chars", req.text.len());
22                let started = adapter.clock().now();
23                let answer = pick_icon(adapter.embedder(), adapter.judge(), adapter.icon_vectors(), &req.text).await;
24                let ms = adapter.clock().now().get().saturating_sub(started.get());
25                match answer {
26                    Ok(Some(icon)) => {
27                        info!("/icon: a picture chosen in {ms} ms");
28                        IconReply::Icon(icon)
29                    }
30                    Ok(None) => {
31                        info!("/icon: none fits ({ms} ms)");
32                        IconReply::NoneFits
33                    }
34                    Err(e) => {
35                        warn!("/icon unavailable after {ms} ms: {e}");
36                        IconReply::Unavailable(e.to_string())
37                    }
38                }
39            }
40            Err(e) => {
41                warn!("/icon: bad request: {}", super::kind_of(&e));
42                IconReply::Unavailable(format!("bad request: {e}"))
43            }
44        };
45        Response::of(&reply)
46    }
47}