1use crate::{
2 error::{self, Error},
3 types::{EpicsString, RequestId},
4};
5
6#[allow(clippy::len_without_is_empty)]
14pub unsafe trait Request: Send + 'static {
15 type Raw: Copy + Send + Sized + 'static;
17 const ID: RequestId;
19
20 fn len(&self) -> usize;
22 unsafe fn from_ptr<'a>(ptr: *const u8, dbr: RequestId, count: usize)
28 -> Result<&'a Self, Error>;
29 fn clone_boxed(&self) -> Box<Self>;
31}
32
33macro_rules! impl_request_methods {
34 () => {
35 fn len(&self) -> usize {
36 1
37 }
38 unsafe fn from_ptr<'a>(
39 ptr: *const u8,
40 dbr: RequestId,
41 count: usize,
42 ) -> Result<&'a Self, Error> {
43 if dbr != Self::ID {
44 Err(error::BADTYPE)
45 } else if count != 1 {
46 Err(error::BADCOUNT)
47 } else {
48 Ok(&*(ptr as *const Self))
49 }
50 }
51 fn clone_boxed(&self) -> Box<Self> {
52 Box::new(*self)
53 }
54 };
55}
56
57pub trait WriteRequest: Request {}
59pub trait ReadRequest: Request {}
61
62#[repr(transparent)]
63#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
64pub struct PutAckt(pub u16);
65
66unsafe impl Request for PutAckt {
67 type Raw = sys::dbr_put_ackt_t;
68 const ID: RequestId = RequestId::PutAckt;
69 impl_request_methods!();
70}
71impl WriteRequest for PutAckt {}
72
73#[repr(transparent)]
74#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
75pub struct PutAcks(pub u16);
76
77unsafe impl Request for PutAcks {
78 type Raw = sys::dbr_put_acks_t;
79 const ID: RequestId = RequestId::PutAcks;
80 impl_request_methods!();
81}
82impl WriteRequest for PutAcks {}
83
84#[repr(transparent)]
85#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
86pub struct ClassName(pub EpicsString);
87
88unsafe impl Request for ClassName {
89 type Raw = sys::dbr_class_name_t;
90 const ID: RequestId = RequestId::ClassName;
91 impl_request_methods!();
92}
93impl ReadRequest for ClassName {}