Skip to main content

rs_teststand/license/
application_license.rs

1//! Which license an application is asking for.
2
3/// The kind of license an application requests (`ApplicationLicenses`).
4///
5/// A host asks for the least it needs. Requesting an editor license on a
6/// station that only has a deployment one fails, so asking high "to be safe"
7/// is how a station that would have worked refuses to start.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9#[non_exhaustive]
10pub enum ApplicationLicense {
11    /// Let the engine decide.
12    Unspecified,
13    /// An operator interface: runs sequences, does not edit them. The right
14    /// request for a headless host.
15    OperatorInterface,
16    /// A custom sequence editor.
17    CustomEditor,
18    /// The full sequence editor.
19    SequenceEditor,
20}
21
22impl ApplicationLicense {
23    /// Maps the engine's number onto a request.
24    ///
25    /// # Errors
26    /// The raw value, when it is one this build does not name.
27    pub const fn from_bits(bits: i32) -> Result<Self, i32> {
28        match bits {
29            0 => Ok(Self::Unspecified),
30            100 => Ok(Self::OperatorInterface),
31            200 => Ok(Self::CustomEditor),
32            300 => Ok(Self::SequenceEditor),
33            unknown => Err(unknown),
34        }
35    }
36
37    /// The engine's number for this request.
38    #[must_use]
39    pub const fn bits(self) -> i32 {
40        match self {
41            Self::Unspecified => 0,
42            Self::OperatorInterface => 100,
43            Self::CustomEditor => 200,
44            Self::SequenceEditor => 300,
45        }
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::ApplicationLicense;
52
53    #[test]
54    fn every_documented_value_round_trips() {
55        for kind in [
56            ApplicationLicense::Unspecified,
57            ApplicationLicense::OperatorInterface,
58            ApplicationLicense::CustomEditor,
59            ApplicationLicense::SequenceEditor,
60        ] {
61            assert_eq!(ApplicationLicense::from_bits(kind.bits()), Ok(kind));
62        }
63    }
64
65    #[test]
66    fn the_values_are_not_ordinals() {
67        // Spaced by hundreds in the type library. Treating them as 0..3 would
68        // request the wrong license and fail on a correctly licensed station.
69        assert_eq!(ApplicationLicense::OperatorInterface.bits(), 100);
70        assert_eq!(ApplicationLicense::SequenceEditor.bits(), 300);
71        assert_eq!(ApplicationLicense::from_bits(1), Err(1));
72    }
73}