use crate::sample::Duration;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Ordinal(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct InterfaceNo(pub u32);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CatalogHash(pub [u8; 32]);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CatalogRef {
pub name: &'static str,
pub hash: CatalogHash,
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Kind {
Signal = 1,
Event = 2,
Command = 3,
Query = 4,
Fixed = 5,
}
pub trait Interface {
const CATALOG: &'static CatalogRef;
const NUMBER: InterfaceNo;
const PROVISIONAL: bool;
const NAME: &'static str;
const MEMBERS: &'static [Member];
}
pub trait Interaction {
type Iface: Interface;
const MEMBER: &'static Member;
}
pub trait Signal: Interaction {
type Payload;
fn init() -> Self::Payload;
}
pub trait Event: Interaction {
type Payload;
}
pub trait Fixed: Interaction {
type Payload;
}
pub trait Command: Interaction {
type Args;
#[allow(
clippy::result_unit_err,
reason = "the failing method decides the contract error, so the error carries no value"
)]
fn require(args: &Self::Args) -> Result<(), ()>;
}
pub trait Query: Interaction {
type Args;
type Reply;
#[allow(
clippy::result_unit_err,
reason = "the failing method decides the contract error, so the error carries no value"
)]
fn require(args: &Self::Args) -> Result<(), ()>;
#[allow(
clippy::result_unit_err,
reason = "the failing method decides the contract error, so the error carries no value"
)]
fn ensure(args: &Self::Args, reply: &Self::Reply) -> Result<(), ()>;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Member {
pub ordinal: Ordinal,
pub kind: Kind,
pub name: &'static str,
pub timing: Option<Timing>,
pub payloads: &'static [PayloadInfo],
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TimingMode {
StrictPeriodic,
Range,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Timing {
pub mode: TimingMode,
pub min: Option<Duration>,
pub max: Option<Duration>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PayloadInfo {
pub type_name: &'static str,
pub max_size: EncodedSizes,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct EncodedSizes {
pub proto3: Option<u32>,
pub flatbuffers: Option<u32>,
pub repr_c: Option<u32>,
}
#[cfg(test)]
mod tests {
use super::{CatalogHash, CatalogRef, Kind};
#[test]
fn catalog_refs_are_equal_only_when_name_and_hash_are_equal() {
let base = CatalogRef {
name: "vehicle",
hash: CatalogHash([1; 32]),
};
let same = CatalogRef {
name: "vehicle",
hash: CatalogHash([1; 32]),
};
let other_hash = CatalogRef {
name: "vehicle",
hash: CatalogHash([2; 32]),
};
let other_name = CatalogRef {
name: "cabin",
hash: CatalogHash([1; 32]),
};
assert_eq!(base, same);
assert_ne!(base, other_hash);
assert_ne!(base, other_name);
}
#[test]
fn kind_values_are_the_language_order_from_one() {
assert_eq!(Kind::Signal as u8, 1);
assert_eq!(Kind::Event as u8, 2);
assert_eq!(Kind::Command as u8, 3);
assert_eq!(Kind::Query as u8, 4);
assert_eq!(Kind::Fixed as u8, 5);
}
}