This repository has no description
1use std::sync::Arc;
2use std::sync::atomic::{AtomicU64, Ordering};
3use std::time::Duration;
4
5use bobbin_runtime::{HttpRequest, MemHttpBody, MemHttpResponder, MemHttpResponse};
6use http::StatusCode;
7use jacquard_common::DefaultStr;
8use jacquard_common::types::did::Did;
9use jacquard_common::types::nsid::Nsid;
10use jacquard_common::types::recordkey::Rkey;
11use url::Url;
12
13const ALPHABET_RKEY: &[u8] = b"abcdefghijklmnopqrstuvwxyz234567";
14const ALPHABET_TID: &[u8] = b"234567abcdefghijklmnopqrstuvwxyz";
15const ENCODED_LEN: usize = 13;
16
17pub fn format_rkey(i: usize) -> String {
18 encode_padded(i.saturating_add(1), ALPHABET_RKEY, b'a')
19}
20
21pub fn format_tid(i: usize) -> String {
22 encode_padded(i.saturating_add(1), ALPHABET_TID, b'2')
23}
24
25fn encode_padded(mut idx: usize, alphabet: &[u8], pad: u8) -> String {
26 let mut buf = [pad; ENCODED_LEN];
27 let mut pos = buf.len();
28 while idx > 0 && pos > 0 {
29 pos -= 1;
30 buf[pos] = alphabet[idx % alphabet.len()];
31 idx /= alphabet.len();
32 }
33 String::from_utf8(buf.to_vec()).unwrap()
34}
35
36pub fn parse_repo_lookup(
37 url: &Url,
38 expected_collection: &Nsid<DefaultStr>,
39) -> Option<(Did<DefaultStr>, Rkey<DefaultStr>)> {
40 let mut repo: Option<Did<DefaultStr>> = None;
41 let mut collection: Option<Nsid<DefaultStr>> = None;
42 let mut rkey: Option<Rkey<DefaultStr>> = None;
43 for (k, v) in url.query_pairs() {
44 match k.as_ref() {
45 "repo" => repo = Did::new_owned(&v).ok(),
46 "collection" => collection = Nsid::new_owned(&v).ok(),
47 "rkey" => rkey = Rkey::new_owned(&v).ok(),
48 _ => {}
49 }
50 }
51 if collection.as_ref()? != expected_collection {
52 return None;
53 }
54 Some((repo?, rkey?))
55}
56
57#[derive(Clone, Default)]
58pub struct AssertNoSlingshot {
59 calls: Arc<AtomicU64>,
60}
61
62impl AssertNoSlingshot {
63 pub fn new() -> Self {
64 Self::default()
65 }
66
67 pub fn calls(&self) -> u64 {
68 self.calls.load(Ordering::Relaxed)
69 }
70}
71
72impl MemHttpResponder for AssertNoSlingshot {
73 fn respond(&self, _: &HttpRequest) -> MemHttpResponse {
74 self.calls.fetch_add(1, Ordering::Relaxed);
75 MemHttpResponse {
76 latency: Duration::ZERO,
77 result: Ok(MemHttpBody::status_only(StatusCode::NOT_FOUND)),
78 }
79 }
80}