1pub const VERSION: &str = version_segment(env!("CARGO_PKG_VERSION"));
10
11#[must_use]
13pub fn url(path: &str) -> String {
14 format!("https://docs.atuin.sh/{VERSION}/{path}")
15}
16
17const fn version_segment(version: &str) -> &str {
18 let bytes = version.as_bytes();
19
20 let mut i = 0;
21 while i < bytes.len() {
22 if bytes[i] == b'-' {
23 return "main";
24 }
25 i += 1;
26 }
27
28 let mut end = 0;
29 let mut dots = 0;
30 while end < bytes.len() {
31 if bytes[end] == b'.' {
32 dots += 1;
33 if dots == 2 {
34 break;
35 }
36 }
37 end += 1;
38 }
39
40 match std::str::from_utf8(bytes.split_at(end).0) {
41 Ok(segment) => segment,
42 Err(_) => "main",
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use rstest::rstest;
49
50 use super::*;
51
52 #[rstest]
53 #[case::stable_patch_zero("18.17.0", "18.17")]
54 #[case::stable_patch_one("18.17.1", "18.17")]
55 #[case::stable_major_bump("19.0.0", "19.0")]
56 #[case::stable_large("100.200.300", "100.200")]
57 #[case::prerelease_beta("18.18.0-beta.2", "main")]
60 #[case::prerelease_beta_older("18.16.0-beta.1", "main")]
61 #[case::prerelease_rc("19.0.0-rc.1", "main")]
62 fn version_segment_maps_release_to_docs_segment(#[case] version: &str, #[case] expected: &str) {
63 assert_eq!(version_segment(version), expected);
64 }
65
66 #[rstest]
67 fn this_build_resolves_to_a_published_version() {
68 assert!(!VERSION.is_empty());
70 assert!(VERSION == "main" || VERSION.split('.').count() == 2);
71 assert!(!VERSION.contains('-'));
72 }
73
74 #[rstest]
75 fn urls_are_absolute_and_versioned() {
76 assert_eq!(
77 url("guide/sync/#login"),
78 format!("https://docs.atuin.sh/{VERSION}/guide/sync/#login")
79 );
80 }
81}