distant_protocol/lib.rs
1#![doc = include_str!("../README.md")]
2
3#[doc = include_str!("../README.md")]
4#[cfg(doctest)]
5pub struct ReadmeDoctests;
6
7mod common;
8mod msg;
9mod request;
10mod response;
11mod utils;
12
13pub use common::*;
14pub use msg::*;
15pub use request::*;
16pub use response::*;
17pub use semver;
18
19/// Protocol version of major/minor/patch.
20///
21/// This should match the version of this crate such that any significant change to the crate
22/// version will also be reflected in this constant that can be used to verify compatibility across
23/// the wire.
24pub const PROTOCOL_VERSION: semver::Version = semver::Version::new(
25 const_str::parse!(env!("CARGO_PKG_VERSION_MAJOR"), u64),
26 const_str::parse!(env!("CARGO_PKG_VERSION_MINOR"), u64),
27 const_str::parse!(env!("CARGO_PKG_VERSION_PATCH"), u64),
28);
29
30/// Comparators used to indicate the [lower, upper) bounds of supported protocol versions.
31const PROTOCOL_VERSION_COMPAT: (semver::Comparator, semver::Comparator) = (
32 semver::Comparator {
33 op: semver::Op::GreaterEq,
34 major: const_str::parse!(env!("CARGO_PKG_VERSION_MAJOR"), u64),
35 minor: Some(const_str::parse!(env!("CARGO_PKG_VERSION_MINOR"), u64)),
36 patch: Some(const_str::parse!(env!("CARGO_PKG_VERSION_PATCH"), u64)),
37 pre: semver::Prerelease::EMPTY,
38 },
39 semver::Comparator {
40 op: semver::Op::Less,
41 major: {
42 let major = const_str::parse!(env!("CARGO_PKG_VERSION_MAJOR"), u64);
43
44 // If we have a version like 0.20, then the upper bound is 0.21,
45 // otherwise if we have a version like 1.2, then the upper bound is 2.0
46 //
47 // So only increment the major if it is greater than 0
48 if major > 0 {
49 major + 1
50 } else {
51 major
52 }
53 },
54 minor: {
55 let major = const_str::parse!(env!("CARGO_PKG_VERSION_MAJOR"), u64);
56 let minor = const_str::parse!(env!("CARGO_PKG_VERSION_MINOR"), u64);
57
58 // If we have a version like 0.20, then the upper bound is 0.21,
59 // otherwise if we have a version like 1.2, then the upper bound is 2.0
60 //
61 // So only increment the minor if major is 0
62 if major > 0 {
63 None
64 } else {
65 Some(minor + 1)
66 }
67 },
68 patch: None,
69 pre: semver::Prerelease::EMPTY,
70 },
71);
72
73/// Returns true if the provided version is compatible with the protocol version.
74///
75/// ```
76/// use distant_protocol::{is_compatible_with, PROTOCOL_VERSION};
77/// use distant_protocol::semver::Version;
78///
79/// // The current protocol version tied to this crate is always compatible
80/// assert!(is_compatible_with(&PROTOCOL_VERSION));
81///
82/// // Major bumps in distant's protocol version are always considered incompatible
83/// assert!(!is_compatible_with(&Version::new(
84/// PROTOCOL_VERSION.major + 1,
85/// PROTOCOL_VERSION.minor,
86/// PROTOCOL_VERSION.patch,
87/// )));
88///
89/// // While distant's protocol is being stabilized, minor version bumps
90/// // are also considered incompatible!
91/// assert!(!is_compatible_with(&Version::new(
92/// PROTOCOL_VERSION.major,
93/// PROTOCOL_VERSION.minor + 1,
94/// PROTOCOL_VERSION.patch,
95/// )));
96///
97/// // Patch bumps in distant's protocol are always considered compatible
98/// assert!(is_compatible_with(&Version::new(
99/// PROTOCOL_VERSION.major,
100/// PROTOCOL_VERSION.minor,
101/// PROTOCOL_VERSION.patch + 1,
102/// )));
103/// ```
104pub fn is_compatible_with(version: &semver::Version) -> bool {
105 let (lower, upper) = PROTOCOL_VERSION_COMPAT;
106
107 lower.matches(version) && upper.matches(version)
108}