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/// The trait carries the encoding's name and nothing else. A payload's size
20/// in an encoding is `Payload<E>::MAX_SIZE` on the payload type, and an
21/// interface's sizes are its table, `Sizes<E>` in `contract`.
22///
23/// A crate outside `ridl-rt` names an encoding through this trait:
24///
25/// ```
26/// fn name<E: ridl_rt::encoding::Encoding>() -> &'static str {
27/// E::NAME
28/// }
29/// assert_eq!(name::<ridl_rt::encoding::ReprC>(), "repr-c");
30/// ```
31///
32/// and cannot add an encoding. The error codes on the `compile_fail` blocks
33/// below document the expected failure, and rustdoc does not check them:
34/// `crates/ridl-rt/tests/seal.rs` compiles each snippet and asserts its code.
35///
36/// ```compile_fail,E0277
37/// struct Json;
38///
39/// impl ridl_rt::encoding::Encoding for Json {
40/// const NAME: &'static str = "json";
41/// }
42/// ```
43///
44/// and cannot implement the sealing trait, because its module is private:
45///
46/// ```compile_fail,E0603
47/// struct Json;
48///
49/// impl ridl_rt::encoding::sealed::Sealed for Json {}
50/// ```
51pub trait Encoding: sealed::Sealed + 'static {
52 /// The encoding's name, spelled as its cargo feature is spelled.
53 const NAME: &'static str;
54}
55
56/// FlatBuffers.
57#[derive(Clone, Copy, Debug, PartialEq, Eq)]
58pub struct FlatBuffers;
59
60/// proto3.
61#[derive(Clone, Copy, Debug, PartialEq, Eq)]
62pub struct Proto3;
63
64/// `repr(C)`, the fixed-layout encoding of ADR-0020 decision 1.
65#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66pub struct ReprC;
67
68impl sealed::Sealed for FlatBuffers {}
69impl sealed::Sealed for Proto3 {}
70impl sealed::Sealed for ReprC {}
71
72impl Encoding for FlatBuffers {
73 const NAME: &'static str = "flatbuffers";
74}
75
76impl Encoding for Proto3 {
77 const NAME: &'static str = "proto3";
78}
79
80impl Encoding for ReprC {
81 const NAME: &'static str = "repr-c";
82}
83
84#[cfg(test)]
85mod tests {
86 use super::{sealed, Encoding, FlatBuffers, Proto3, ReprC};
87
88 /// A fourth encoding, for this test only. It implements every required
89 /// item of `Encoding`, so a required item added to the trait fails to
90 /// compile this module.
91 struct Fourth;
92
93 impl sealed::Sealed for Fourth {}
94
95 impl Encoding for Fourth {
96 const NAME: &'static str = "fourth";
97 }
98
99 #[test]
100 fn name_is_the_only_required_item() {
101 assert_eq!(Fourth::NAME, "fourth");
102 }
103
104 #[test]
105 fn each_name_is_the_cargo_feature_name() {
106 assert_eq!(FlatBuffers::NAME, "flatbuffers");
107 assert_eq!(Proto3::NAME, "proto3");
108 assert_eq!(ReprC::NAME, "repr-c");
109 }
110}