ridl_rt/encoding.rs
1//! The payload encodings (ADR-0020 decisions 1 and 5).
2//!
3//! An encoding is a marker type. A payload type implements `Payload<E>` once
4//! for each encoding its package was built with, so one type can carry several
5//! codecs. The set of encodings is closed: [`Encoding`] is sealed, so a new
6//! encoding is a decision recorded in an ADR and not an `impl` in another
7//! crate.
8//!
9//! The marker types do not depend on a cargo feature. A runtime can name every
10//! encoding without linking a codec.
11
12mod sealed {
13 pub trait Sealed {}
14}
15
16/// A payload encoding. Only the three marker types of this module implement
17/// it.
18///
19/// A crate outside `ridl-rt` names an encoding through this trait:
20///
21/// ```
22/// fn name<E: ridl_rt::encoding::Encoding>() -> &'static str {
23/// E::NAME
24/// }
25/// assert_eq!(name::<ridl_rt::encoding::ReprC>(), "repr-c");
26/// ```
27///
28/// and cannot add an encoding:
29///
30/// ```compile_fail,E0277
31/// struct Json;
32///
33/// impl ridl_rt::encoding::Encoding for Json {
34/// const NAME: &'static str = "json";
35/// }
36/// ```
37///
38/// and cannot implement the sealing trait, because its module is private:
39///
40/// ```compile_fail,E0603
41/// struct Json;
42///
43/// impl ridl_rt::encoding::sealed::Sealed for Json {}
44/// ```
45pub trait Encoding: sealed::Sealed + 'static {
46 /// The encoding's name, spelled as its cargo feature is spelled.
47 const NAME: &'static str;
48}
49
50/// FlatBuffers.
51#[derive(Clone, Copy, Debug, PartialEq, Eq)]
52pub struct FlatBuffers;
53
54/// proto3.
55#[derive(Clone, Copy, Debug, PartialEq, Eq)]
56pub struct Proto3;
57
58/// `repr(C)`, the fixed-layout encoding of ADR-0020 decision 1.
59#[derive(Clone, Copy, Debug, PartialEq, Eq)]
60pub struct ReprC;
61
62impl sealed::Sealed for FlatBuffers {}
63impl sealed::Sealed for Proto3 {}
64impl sealed::Sealed for ReprC {}
65
66impl Encoding for FlatBuffers {
67 const NAME: &'static str = "flatbuffers";
68}
69
70impl Encoding for Proto3 {
71 const NAME: &'static str = "proto3";
72}
73
74impl Encoding for ReprC {
75 const NAME: &'static str = "repr-c";
76}
77
78#[cfg(test)]
79mod tests {
80 use super::{sealed, Encoding, FlatBuffers, Proto3, ReprC};
81
82 /// A fourth encoding, for this test only. It implements every required
83 /// item of `Encoding`, so a required item added to the trait fails to
84 /// compile this module.
85 struct Fourth;
86
87 impl sealed::Sealed for Fourth {}
88
89 impl Encoding for Fourth {
90 const NAME: &'static str = "fourth";
91 }
92
93 #[test]
94 fn name_is_the_only_required_item() {
95 assert_eq!(Fourth::NAME, "fourth");
96 }
97
98 #[test]
99 fn each_name_is_the_cargo_feature_name() {
100 assert_eq!(FlatBuffers::NAME, "flatbuffers");
101 assert_eq!(Proto3::NAME, "proto3");
102 assert_eq!(ReprC::NAME, "repr-c");
103 }
104}