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}