Skip to content

Commit 8f48c37

Browse files
committed
context_server
1 parent 54e0bdb commit 8f48c37

File tree

8 files changed

+120
-35
lines changed

8 files changed

+120
-35
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/bencher_context/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ publish = false
88

99
[features]
1010
client = ["dep:gix", "dep:uuid", "dep:windows"]
11+
server = ["bencher_valid/server"]
1112
schema = ["dep:schemars"]
1213

1314
[dependencies]
1415
# Workspace
16+
bencher_valid = { workspace = true, optional = true }
1517
gix = { workspace = true, optional = true, features = ["revision"] }
1618
schemars = { workspace = true, optional = true }
1719
serde.workspace = true

lib/bencher_context/src/lib.rs

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use serde::{Deserialize, Serialize};
66

77
#[cfg(feature = "client")]
88
mod client;
9+
#[cfg(feature = "server")]
10+
mod server;
911

1012
#[cfg(feature = "client")]
1113
pub use client::Fingerprint;
@@ -15,39 +17,6 @@ pub use client::Fingerprint;
1517
#[cfg_attr(feature = "schema", derive(JsonSchema))]
1618
pub struct ReportContext(pub HashMap<String, String>);
1719

18-
#[allow(clippy::multiple_inherent_impl)]
19-
impl ReportContext {
20-
pub fn repo_name(&self) -> Option<&str> {
21-
self.0.get(ContextPath::REPO_NAME).map(String::as_str)
22-
}
23-
24-
pub fn repo_hash(&self) -> Option<&str> {
25-
self.0.get(ContextPath::REPO_HASH).map(String::as_str)
26-
}
27-
28-
pub fn branch_ref(&self) -> Option<&str> {
29-
self.0.get(ContextPath::BRANCH_REF).map(String::as_str)
30-
}
31-
32-
pub fn branch_ref_name(&self) -> Option<&str> {
33-
self.0.get(ContextPath::BRANCH_REF_NAME).map(String::as_str)
34-
}
35-
36-
pub fn branch_hash(&self) -> Option<&str> {
37-
self.0.get(ContextPath::BRANCH_HASH).map(String::as_str)
38-
}
39-
40-
pub fn testbed_os(&self) -> Option<&str> {
41-
self.0.get(ContextPath::TESTBED_OS).map(String::as_str)
42-
}
43-
44-
pub fn testbed_fingerprint(&self) -> Option<&str> {
45-
self.0
46-
.get(ContextPath::TESTBED_FINGERPRINT)
47-
.map(String::as_str)
48-
}
49-
}
50-
5120
struct ContextPath;
5221

5322
impl ContextPath {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use bencher_valid::BASE_36;
2+
3+
const BASE: u128 = 36;
4+
const MAX_CHUNK_SIZE: usize = 16;
5+
6+
pub fn encode_base36(input: &str) -> String {
7+
let mut result = String::new();
8+
let chars = BASE_36.chars().collect::<Vec<_>>();
9+
10+
for chunk in input.as_bytes().chunks(MAX_CHUNK_SIZE) {
11+
let mut num = chunk.iter().fold(0u128, |acc, &c| {
12+
acc * (u128::from(u8::MAX) + 1) + u128::from(c)
13+
});
14+
15+
while num > 0 {
16+
let remainder = (num % BASE) as usize;
17+
if let Some(c) = chars.get(remainder) {
18+
result.push(*c);
19+
}
20+
num /= BASE;
21+
}
22+
}
23+
24+
result.chars().rev().collect()
25+
}
26+
27+
#[cfg(test)]
28+
mod tests {
29+
use super::*;
30+
31+
#[test]
32+
fn test_encode_base36_empty() {
33+
assert_eq!(encode_base36(""), "");
34+
}
35+
36+
#[test]
37+
fn test_encode_base36_single_char() {
38+
assert_eq!(encode_base36("a"), "2p");
39+
}
40+
41+
#[test]
42+
fn test_encode_base36_hello_world() {
43+
assert_eq!(encode_base36("Hello, World!"), "fg3h7vqw7een6jwwnzmp");
44+
}
45+
46+
#[test]
47+
fn test_encode_base36_max_chunk_size() {
48+
let max_length_string = "a".repeat(MAX_CHUNK_SIZE);
49+
assert_eq!(
50+
encode_base36(&max_length_string),
51+
"5rjn2eqj5uddxxihjq3vmi99d"
52+
);
53+
}
54+
55+
#[test]
56+
fn test_encode_base36_double() {
57+
let max_length_string = "a".repeat(MAX_CHUNK_SIZE * 2);
58+
assert_eq!(
59+
encode_base36(&max_length_string),
60+
"5rjn2eqj5uddxxihjq3vmi99d5rjn2eqj5uddxxihjq3vmi99d"
61+
);
62+
}
63+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use bencher_valid::Slug;
2+
3+
use crate::{ContextPath, ReportContext};
4+
5+
mod base_36;
6+
7+
#[allow(clippy::multiple_inherent_impl)]
8+
impl ReportContext {
9+
pub fn slug(&self) -> Slug {
10+
let name = self.repo_name();
11+
let hash = self.repo_hash();
12+
13+
todo!()
14+
}
15+
16+
pub fn repo_name(&self) -> Option<&str> {
17+
self.0.get(ContextPath::REPO_NAME).map(String::as_str)
18+
}
19+
20+
pub fn repo_hash(&self) -> Option<&str> {
21+
self.0.get(ContextPath::REPO_HASH).map(String::as_str)
22+
}
23+
24+
pub fn branch_ref(&self) -> Option<&str> {
25+
self.0.get(ContextPath::BRANCH_REF).map(String::as_str)
26+
}
27+
28+
pub fn branch_ref_name(&self) -> Option<&str> {
29+
self.0.get(ContextPath::BRANCH_REF_NAME).map(String::as_str)
30+
}
31+
32+
pub fn branch_hash(&self) -> Option<&str> {
33+
self.0.get(ContextPath::BRANCH_HASH).map(String::as_str)
34+
}
35+
36+
pub fn testbed_os(&self) -> Option<&str> {
37+
self.0.get(ContextPath::TESTBED_OS).map(String::as_str)
38+
}
39+
40+
pub fn testbed_fingerprint(&self) -> Option<&str> {
41+
self.0
42+
.get(ContextPath::TESTBED_FINGERPRINT)
43+
.map(String::as_str)
44+
}
45+
}

lib/bencher_json/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ publish = false
99
[features]
1010
client = ["bencher_context/client", "bencher_valid/client"]
1111
table = ["dep:tabled"]
12-
server = ["bencher_valid/server"]
12+
server = ["bencher_context/server", "bencher_valid/server"]
1313
schema = ["dep:schemars", "bencher_context/schema", "ordered-float/schemars"]
1414
db = ["dep:diesel", "dep:serde_yaml", "bencher_valid/db"]
1515
plus = ["bencher_valid/plus"]

lib/bencher_valid/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ mod user_name;
2828

2929
pub use crate::git_hash::GitHash;
3030
pub use crate::slug::Slug;
31+
#[cfg(feature = "server")]
32+
pub use crate::slug::BASE_36;
3133
pub use crate::url::Url;
3234
pub use benchmark_name::BenchmarkName;
3335
pub use branch_name::BranchName;

lib/bencher_valid/src/slug.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use serde::{
1212

1313
use crate::{is_valid_len, ValidError, MAX_LEN};
1414

15+
#[cfg(feature = "server")]
16+
pub const BASE_36: &str = "0123456789abcdefghijklmnopqrstuvwxyz";
17+
1518
#[typeshare::typeshare]
1619
#[derive(Debug, Display, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize)]
1720
#[cfg_attr(feature = "schema", derive(JsonSchema))]
@@ -115,7 +118,7 @@ impl Slug {
115118
pub fn rand_suffix() -> String {
116119
use rand::Rng;
117120

118-
const CHARSET: &[u8] = b"0123456789abcdefghijklmnopqrstuvwxyz";
121+
const CHARSET: &[u8] = BASE_36.as_bytes();
119122
let mut rng = rand::rng();
120123

121124
(0..Self::RAND_LEN)

0 commit comments

Comments
 (0)