1use super::*;
2use rbp_cards::*;
3use std::sync::Arc;
4use tokio_postgres::Client;
5
6#[async_trait::async_trait]
9pub trait Check: Send + Sync {
10 async fn epochs(&self) -> usize;
11 async fn blueprint(&self) -> usize;
12 async fn clustered(&self, street: Street) -> bool;
13 async fn status(&self) {
14 fn commas(n: usize) -> String {
15 n.to_string()
16 .as_bytes()
17 .rchunks(3)
18 .rev()
19 .map(std::str::from_utf8)
20 .map(Result::unwrap)
21 .collect::<Vec<_>>()
22 .join(",")
23 }
24 log::info!("┌────────────┬───────────────┐");
25 log::info!("│ Street │ Clustered │");
26 log::info!("├────────────┼───────────────┤");
27 for street in Street::all().iter().rev().cloned() {
28 let done = self.clustered(street).await;
29 let mark = if done { "✓" } else { " " };
30 log::info!(
31 "│ {:?}{} │ {} │",
32 street,
33 " ".repeat(10 - format!("{:?}", street).len()),
34 mark
35 );
36 }
37 log::info!("├────────────┼───────────────┤");
38 log::info!("│ Epoch │ {:>13} │", commas(self.epochs().await));
39 log::info!("│ Blueprint │ {:>13} │", commas(self.blueprint().await));
40 log::info!("└────────────┴───────────────┘");
41 }
42}
43
44#[async_trait::async_trait]
45impl Check for Client {
46 async fn epochs(&self) -> usize {
47 let sql = format!("SELECT value FROM {t} WHERE key = 'current'", t = EPOCH);
48 self.query_opt(&sql, &[])
49 .await
50 .ok()
51 .flatten()
52 .map(|r| r.get::<_, i64>(0) as usize)
53 .unwrap_or(0)
54 }
55 async fn blueprint(&self) -> usize {
56 let sql = format!("SELECT COUNT(*) FROM {t}", t = BLUEPRINT);
57 self.query_opt(&sql, &[])
58 .await
59 .ok()
60 .flatten()
61 .map(|r| r.get::<_, i64>(0) as usize)
62 .unwrap_or(0)
63 }
64 async fn clustered(&self, street: Street) -> bool {
65 let sql = format!("SELECT 1 FROM {t} WHERE obs = $1", t = ISOMORPHISM);
66 let obs = i64::from(Isomorphism::from(Observation::from(street)));
67 self.query_opt(&sql, &[&obs]).await.ok().flatten().is_some()
68 }
69}
70
71#[async_trait::async_trait]
72impl Check for Arc<Client> {
73 async fn epochs(&self) -> usize {
74 self.as_ref().epochs().await
75 }
76 async fn blueprint(&self) -> usize {
77 self.as_ref().blueprint().await
78 }
79 async fn clustered(&self, street: Street) -> bool {
80 self.as_ref().clustered(street).await
81 }
82}