1use core::fmt;
9
10use minicbor::data::Type;
11use minicbor::decode::{self, Decoder};
12use minicbor::encode::{self, Encoder, Write};
13use minicbor::{Decode, Encode};
14
15use crate::capability::Capabilities;
16use crate::cbor::{self, Elements};
17use crate::error::Error;
18use crate::event::{Event, Stream};
19use crate::snapshot::{Bounds, Snapshot};
20
21pub mod kind {
23 pub const HELLO: u8 = 0;
24 pub const WELCOME: u8 = 1;
25 pub const REQUEST: u8 = 2;
26 pub const RESPONSE: u8 = 3;
27 pub const EVENT: u8 = 4;
28 pub const PING: u8 = 5;
29 pub const PONG: u8 = 6;
30
31 pub fn name(kind: u8) -> &'static str {
33 match kind {
34 HELLO => "hello",
35 WELCOME => "welcome",
36 REQUEST => "request",
37 RESPONSE => "response",
38 EVENT => "event",
39 PING => "ping",
40 PONG => "pong",
41 _ => "unknown kind",
42 }
43 }
44}
45
46#[derive(Clone, Debug, PartialEq, Eq)]
48pub enum Message {
49 Hello(Hello),
50 Welcome(Welcome),
51 Request(Request),
52 Response(Response),
53 Event(Event),
54 Ping(Ping),
55 Pong(Pong),
56}
57
58impl Message {
59 pub fn kind(&self) -> u8 {
61 match self {
62 Message::Hello(_) => kind::HELLO,
63 Message::Welcome(_) => kind::WELCOME,
64 Message::Request(_) => kind::REQUEST,
65 Message::Response(_) => kind::RESPONSE,
66 Message::Event(_) => kind::EVENT,
67 Message::Ping(_) => kind::PING,
68 Message::Pong(_) => kind::PONG,
69 }
70 }
71
72 pub fn encode(&self, out: &mut Vec<u8>) {
74 minicbor::encode(self, out).expect("encoding into a Vec cannot fail");
75 }
76
77 pub fn to_vec(&self) -> Vec<u8> {
79 let mut out = Vec::new();
80 self.encode(&mut out);
81 out
82 }
83
84 pub fn decode(bytes: &[u8]) -> Result<Message, DecodeError> {
86 let mut d = Decoder::new(bytes);
87 let msg = match peek_kind(&d)? {
88 kind::HELLO => Message::Hello(d.decode()?),
89 kind::WELCOME => Message::Welcome(d.decode()?),
90 kind::REQUEST => Message::Request(d.decode()?),
91 kind::RESPONSE => Message::Response(d.decode()?),
92 kind::EVENT => Message::Event(d.decode()?),
93 kind::PING => Message::Ping(d.decode()?),
94 kind::PONG => Message::Pong(d.decode()?),
95 other => return Err(DecodeError::UnknownKind(other)),
96 };
97 if d.position() != bytes.len() {
98 return Err(DecodeError::TrailingBytes {
99 consumed: d.position(),
100 len: bytes.len(),
101 });
102 }
103 Ok(msg)
104 }
105}
106
107fn peek_kind(d: &Decoder<'_>) -> Result<u8, decode::Error> {
110 let mut p = d.clone();
111 match p.datatype()? {
112 Type::Array | Type::ArrayIndef => {
113 let mut items = Elements::begin(&mut p)?;
114 items.require(&mut p, 0, "kind", |d| d.u8())
115 }
116 Type::Map | Type::MapIndef => {
117 let len = p.map()?;
119 let mut seen = 0;
120 loop {
121 let more = match len {
122 Some(n) => seen < n,
123 None => p.datatype()? != Type::Break,
124 };
125 if !more {
126 return Err(cbor::missing(0, "kind").at(d.position()));
127 }
128 if p.i64()? == 0 {
129 return p.u8();
130 }
131 p.skip()?;
132 seen += 1;
133 }
134 }
135 other => Err(decode::Error::type_mismatch(other)
136 .with_message("a message is a map or an array")
137 .at(d.position())),
138 }
139}
140
141impl<C> Encode<C> for Message {
142 fn encode<W: Write>(
143 &self,
144 e: &mut Encoder<W>,
145 ctx: &mut C,
146 ) -> Result<(), encode::Error<W::Error>> {
147 match self {
148 Message::Hello(m) => m.encode(e, ctx),
149 Message::Welcome(m) => m.encode(e, ctx),
150 Message::Request(m) => m.encode(e, ctx),
151 Message::Response(m) => m.encode(e, ctx),
152 Message::Event(m) => m.encode(e, ctx),
153 Message::Ping(m) => m.encode(e, ctx),
154 Message::Pong(m) => m.encode(e, ctx),
155 }
156 }
157}
158
159impl From<Hello> for Message {
160 fn from(m: Hello) -> Message {
161 Message::Hello(m)
162 }
163}
164
165impl From<Welcome> for Message {
166 fn from(m: Welcome) -> Message {
167 Message::Welcome(m)
168 }
169}
170
171impl From<Request> for Message {
172 fn from(m: Request) -> Message {
173 Message::Request(m)
174 }
175}
176
177impl From<Response> for Message {
178 fn from(m: Response) -> Message {
179 Message::Response(m)
180 }
181}
182
183impl From<Event> for Message {
184 fn from(m: Event) -> Message {
185 Message::Event(m)
186 }
187}
188
189#[derive(Debug)]
191pub enum DecodeError {
192 Cbor(minicbor::decode::Error),
194 UnknownKind(u8),
196 TrailingBytes { consumed: usize, len: usize },
198}
199
200impl fmt::Display for DecodeError {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 match self {
203 DecodeError::Cbor(e) => write!(f, "invalid message: {e}"),
204 DecodeError::UnknownKind(k) => write!(f, "unknown message kind {k}"),
205 DecodeError::TrailingBytes { consumed, len } => write!(
206 f,
207 "{} bytes after the message, which ends at byte {consumed} of {len}",
208 len - consumed
209 ),
210 }
211 }
212}
213
214impl std::error::Error for DecodeError {}
215
216impl From<minicbor::decode::Error> for DecodeError {
217 fn from(e: minicbor::decode::Error) -> DecodeError {
218 DecodeError::Cbor(e)
219 }
220}
221
222#[derive(Clone, Debug, PartialEq, Eq)]
226pub struct Hello {
227 pub versions: Vec<u16>,
229 pub capabilities: Capabilities,
230 pub max_frame: u32,
232 pub agent: String,
234 pub token: Option<String>,
236}
237
238#[derive(Clone, Debug, PartialEq, Eq)]
243pub struct Welcome {
244 pub versions: Vec<u16>,
246 pub version: Option<u16>,
248 pub max_frame: u32,
250 pub error: Option<Error>,
252}
253
254#[derive(Clone, Debug, PartialEq, Eq)]
259pub struct Request {
260 pub id: u32,
262 pub deadline_ms: Option<u32>,
264 pub call: Call,
266}
267
268#[derive(Clone, Debug, PartialEq, Eq)]
273pub struct Response {
274 pub id: u32,
276 pub method: Method,
278 pub result: Result<Reply, Error>,
279}
280
281#[derive(Clone, Copy, Debug, PartialEq, Eq)]
285pub struct Ping {
286 pub nonce: u64,
287}
288
289#[derive(Clone, Copy, Debug, PartialEq, Eq)]
293pub struct Pong {
294 pub nonce: u64,
295}
296
297wire_enum! {
298 pub struct Method(u16);
300 SNAPSHOT = 1, "snapshot";
302 SCREENSHOT = 2, "screenshot";
304 TAP = 3, "tap";
306 SWIPE = 4, "swipe";
308 KEY = 5, "key";
310 TEXT_SET = 6, "text_set";
312 FRAMES_START = 7, "frames_start";
314 FRAMES_STOP = 8, "frames_stop";
316 RESYNC = 9, "resync";
318 SHUTDOWN = 10, "shutdown";
320 BOUNDS = 11, "bounds";
323}
324
325impl Method {
326 pub fn required_capability(self) -> Capabilities {
329 match self {
330 Method::SNAPSHOT => Capabilities::TREE,
331 Method::SCREENSHOT => Capabilities::SCREENSHOT,
332 Method::TAP | Method::SWIPE | Method::KEY => Capabilities::INPUT,
333 Method::TEXT_SET => Capabilities::TEXT_SET,
334 Method::FRAMES_START | Method::FRAMES_STOP => Capabilities::FRAMES,
335 Method::RESYNC => Capabilities::EVENTS,
336 Method::BOUNDS => Capabilities::BOUNDS,
337 _ => Capabilities::NONE,
338 }
339 }
340}
341
342#[derive(Clone, Debug, PartialEq, Eq)]
344pub enum Call {
345 Snapshot(SnapshotParams),
346 Screenshot(ScreenshotParams),
347 Tap(TapParams),
348 Swipe(SwipeParams),
349 Key(KeyParams),
350 TextSet(TextParams),
351 FramesStart(FramesParams),
352 FramesStop,
353 Resync(ResyncParams),
354 Shutdown,
355 Bounds(BoundsParams),
356 Unknown(Method),
359}
360
361impl Call {
362 pub fn method(&self) -> Method {
363 match self {
364 Call::Snapshot(_) => Method::SNAPSHOT,
365 Call::Screenshot(_) => Method::SCREENSHOT,
366 Call::Tap(_) => Method::TAP,
367 Call::Swipe(_) => Method::SWIPE,
368 Call::Key(_) => Method::KEY,
369 Call::TextSet(_) => Method::TEXT_SET,
370 Call::FramesStart(_) => Method::FRAMES_START,
371 Call::FramesStop => Method::FRAMES_STOP,
372 Call::Resync(_) => Method::RESYNC,
373 Call::Shutdown => Method::SHUTDOWN,
374 Call::Bounds(_) => Method::BOUNDS,
375 Call::Unknown(method) => *method,
376 }
377 }
378}
379
380#[derive(Clone, Debug, PartialEq, Eq)]
382pub enum Reply {
383 Snapshot(Snapshot),
385 Screenshot(Screenshot),
387 Input(InputAck),
389 Text(TextAck),
391 Resync(ResyncAck),
393 Bounds(Probed),
395 Empty,
397}
398
399#[derive(Clone, Debug, Default, PartialEq, Eq, Encode, Decode)]
401#[cbor(map)]
402pub struct SnapshotParams {
403 #[n(0)]
405 pub max_depth: Option<u32>,
406 #[n(1)]
408 pub max_nodes: Option<u32>,
409 #[n(2)]
411 pub idle_ms: Option<u32>,
412 #[n(3)]
418 pub evict_event_less: Option<bool>,
419 #[n(4)]
425 pub evict: Option<Vec<u32>>,
426}
427
428#[derive(Clone, Debug, Default, PartialEq, Eq, Encode, Decode)]
430#[cbor(map)]
431pub struct ScreenshotParams {
432 #[n(0)]
433 pub format: Option<ImageFormat>,
434 #[n(1)]
436 pub quality: Option<u8>,
437 #[n(2)]
439 pub max_dimension: Option<u32>,
440}
441
442#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
444#[cbor(map)]
445pub struct TapParams {
446 #[n(0)]
447 pub x: i32,
448 #[n(1)]
449 pub y: i32,
450 #[n(2)]
451 pub duration_ms: Option<u32>,
452}
453
454#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
458#[cbor(map)]
459pub struct SwipeParams {
460 #[n(0)]
461 pub x1: i32,
462 #[n(1)]
463 pub y1: i32,
464 #[n(2)]
465 pub x2: i32,
466 #[n(3)]
467 pub y2: i32,
468 #[n(4)]
469 pub duration_ms: u32,
470 #[n(5)]
476 pub rest_ms: Option<u32>,
477}
478
479#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
481#[cbor(map)]
482pub struct KeyParams {
483 #[n(0)]
485 pub code: u32,
486 #[n(1)]
488 pub meta: Option<u32>,
489}
490
491#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
493#[cbor(map)]
494pub struct TextParams {
495 #[n(0)]
496 pub text: String,
497 #[n(1)]
499 pub node: Option<u32>,
500 #[n(2)]
502 pub mode: Option<TextMethod>,
503}
504
505#[derive(Clone, Debug, Default, PartialEq, Eq, Encode, Decode)]
507#[cbor(map)]
508pub struct FramesParams {
509 #[n(0)]
510 pub max_fps: Option<u32>,
511 #[n(1)]
512 pub max_dimension: Option<u32>,
513}
514
515#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
517#[cbor(map)]
518pub struct ResyncParams {
519 #[n(0)]
520 pub stream: Stream,
521}
522
523#[derive(Clone, Debug, Default, PartialEq, Eq, Encode, Decode)]
526#[cbor(map)]
527pub struct BoundsParams {
528 #[cbor(n(0), decode_with = "crate::cbor::decode_vec")]
529 pub nodes: Vec<u32>,
530}
531
532#[derive(Clone, Debug, Default, PartialEq, Eq, Encode, Decode)]
536#[cbor(map)]
537pub struct Probed {
538 #[cbor(n(0), decode_with = "crate::cbor::decode_vec")]
539 pub nodes: Vec<NodeBounds>,
540}
541
542#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Encode, Decode)]
544#[cbor(array)]
545pub struct NodeBounds {
546 #[n(0)]
548 pub node: u32,
549 #[n(1)]
551 pub bounds: Bounds,
552}
553
554#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
556#[cbor(map)]
557pub struct Screenshot {
558 #[n(0)]
559 pub format: ImageFormat,
560 #[n(1)]
561 pub width: u32,
562 #[n(2)]
563 pub height: u32,
564 #[n(3)]
566 pub rotation: Rotation,
567 #[cbor(n(4), with = "minicbor::bytes")]
569 pub data: Vec<u8>,
570}
571
572#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
574#[cbor(map)]
575pub struct InputAck {
576 #[n(0)]
577 pub accepted: bool,
578}
579
580#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
582#[cbor(map)]
583pub struct TextAck {
584 #[n(0)]
585 pub method: TextMethod,
586}
587
588#[derive(Clone, Debug, PartialEq, Eq, Encode, Decode)]
590#[cbor(map)]
591pub struct ResyncAck {
592 #[n(0)]
593 pub stream: Stream,
594 #[n(1)]
596 pub seq: u64,
597}
598
599wire_enum! {
600 pub struct ImageFormat(u8);
602 PNG = 0, "png";
603 JPEG = 1, "jpeg";
604}
605
606wire_enum! {
607 pub struct Rotation(u8);
609 R0 = 0, "0";
610 R90 = 1, "90";
611 R180 = 2, "180";
612 R270 = 3, "270";
613}
614
615wire_enum! {
616 pub struct TextMethod(u8);
618 AUTO = 0, "auto";
620 DIRECT = 1, "direct";
622 KEYS = 2, "keys";
624}
625
626impl<C> Encode<C> for Hello {
627 fn encode<W: Write>(
628 &self,
629 e: &mut Encoder<W>,
630 ctx: &mut C,
631 ) -> Result<(), encode::Error<W::Error>> {
632 e.map(5 + u64::from(self.token.is_some()))?;
633 e.u8(0)?.u8(kind::HELLO)?;
634 e.u8(1)?.encode_with(&self.versions, ctx)?;
635 e.u8(2)?.encode_with(self.capabilities, ctx)?;
636 e.u8(3)?.u32(self.max_frame)?;
637 e.u8(4)?.str(&self.agent)?;
638 if let Some(token) = &self.token {
639 e.u8(5)?.str(token)?;
640 }
641 Ok(())
642 }
643}
644
645impl<'b, C> Decode<'b, C> for Hello {
646 fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Hello, decode::Error> {
647 let at = d.position();
648 let mut k = None;
649 let mut versions = None;
650 let mut capabilities = None;
651 let mut max_frame = None;
652 let mut agent = None;
653 let mut token = None;
654 cbor::map_entries(d, |d, key| {
655 match key {
656 0 => k = Some(d.u8()?),
657 1 => versions = Some(cbor::decode_vec(d, &mut *ctx)?),
658 2 => capabilities = Some(Capabilities::decode(d, &mut *ctx)?),
659 3 => max_frame = Some(d.u32()?),
660 4 => agent = Some(d.str()?.to_owned()),
661 5 => token = Option::<String>::decode(d, &mut *ctx)?,
662 _ => d.skip()?,
663 }
664 Ok(())
665 })?;
666 cbor::expect_kind(k, kind::HELLO, at)?;
667 Ok(Hello {
668 versions: versions.ok_or_else(|| cbor::missing(1, "versions").at(at))?,
669 capabilities: capabilities.ok_or_else(|| cbor::missing(2, "capabilities").at(at))?,
670 max_frame: max_frame.ok_or_else(|| cbor::missing(3, "max_frame").at(at))?,
671 agent: agent.ok_or_else(|| cbor::missing(4, "agent").at(at))?,
672 token,
673 })
674 }
675}
676
677impl<C> Encode<C> for Welcome {
678 fn encode<W: Write>(
679 &self,
680 e: &mut Encoder<W>,
681 ctx: &mut C,
682 ) -> Result<(), encode::Error<W::Error>> {
683 e.map(3 + u64::from(self.version.is_some()) + u64::from(self.error.is_some()))?;
684 e.u8(0)?.u8(kind::WELCOME)?;
685 e.u8(1)?.encode_with(&self.versions, ctx)?;
686 if let Some(version) = self.version {
687 e.u8(2)?.u16(version)?;
688 }
689 e.u8(3)?.u32(self.max_frame)?;
690 if let Some(error) = &self.error {
691 e.u8(4)?.encode_with(error, ctx)?;
692 }
693 Ok(())
694 }
695}
696
697impl<'b, C> Decode<'b, C> for Welcome {
698 fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Welcome, decode::Error> {
699 let at = d.position();
700 let mut k = None;
701 let mut versions = None;
702 let mut version = None;
703 let mut max_frame = None;
704 let mut error = None;
705 cbor::map_entries(d, |d, key| {
706 match key {
707 0 => k = Some(d.u8()?),
708 1 => versions = Some(cbor::decode_vec(d, &mut *ctx)?),
709 2 => version = Option::<u16>::decode(d, &mut *ctx)?,
710 3 => max_frame = Some(d.u32()?),
711 4 => error = Option::<Error>::decode(d, &mut *ctx)?,
712 _ => d.skip()?,
713 }
714 Ok(())
715 })?;
716 cbor::expect_kind(k, kind::WELCOME, at)?;
717 Ok(Welcome {
718 versions: versions.ok_or_else(|| cbor::missing(1, "versions").at(at))?,
719 version,
720 max_frame: max_frame.ok_or_else(|| cbor::missing(3, "max_frame").at(at))?,
721 error,
722 })
723 }
724}
725
726impl<C> Encode<C> for Request {
727 fn encode<W: Write>(
728 &self,
729 e: &mut Encoder<W>,
730 ctx: &mut C,
731 ) -> Result<(), encode::Error<W::Error>> {
732 e.map(4 + u64::from(self.deadline_ms.is_some()))?;
733 e.u8(0)?.u8(kind::REQUEST)?;
734 e.u8(1)?.u32(self.id)?;
735 e.u8(2)?.u16(self.call.method().0)?;
736 if let Some(ms) = self.deadline_ms {
737 e.u8(3)?.u32(ms)?;
738 }
739 e.u8(4)?;
740 match &self.call {
741 Call::Snapshot(p) => p.encode(e, ctx)?,
742 Call::Screenshot(p) => p.encode(e, ctx)?,
743 Call::Tap(p) => p.encode(e, ctx)?,
744 Call::Swipe(p) => p.encode(e, ctx)?,
745 Call::Key(p) => p.encode(e, ctx)?,
746 Call::TextSet(p) => p.encode(e, ctx)?,
747 Call::FramesStart(p) => p.encode(e, ctx)?,
748 Call::Resync(p) => p.encode(e, ctx)?,
749 Call::Bounds(p) => p.encode(e, ctx)?,
750 Call::FramesStop | Call::Shutdown | Call::Unknown(_) => {
751 e.map(0)?;
752 }
753 }
754 Ok(())
755 }
756}
757
758impl<'b, C> Decode<'b, C> for Request {
759 fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Request, decode::Error> {
760 let at = d.position();
761 let mut k = None;
762 let mut id = None;
763 let mut method = None;
764 let mut deadline_ms = None;
765 let mut params_at = None;
766 cbor::map_entries(d, |d, key| {
767 match key {
768 0 => k = Some(d.u8()?),
769 1 => id = Some(d.u32()?),
770 2 => method = Some(Method(d.u16()?)),
771 3 => deadline_ms = Option::<u32>::decode(d, &mut *ctx)?,
772 4 => {
774 params_at = Some(d.position());
775 d.skip()?;
776 }
777 _ => d.skip()?,
778 }
779 Ok(())
780 })?;
781 cbor::expect_kind(k, kind::REQUEST, at)?;
782 let id = id.ok_or_else(|| cbor::missing(1, "id").at(at))?;
783 let method = method.ok_or_else(|| cbor::missing(2, "method").at(at))?;
784 let params_at = params_at.ok_or_else(|| cbor::missing(4, "params").at(at))?;
785 let mut params = d.clone();
786 params.set_position(params_at);
787 let call = Call::decode_params(method, &mut params, ctx)?;
788 Ok(Request {
789 id,
790 deadline_ms,
791 call,
792 })
793 }
794}
795
796impl Call {
797 fn decode_params<'b, C>(
798 method: Method,
799 d: &mut Decoder<'b>,
800 ctx: &mut C,
801 ) -> Result<Call, decode::Error> {
802 Ok(match method {
803 Method::SNAPSHOT => Call::Snapshot(Decode::decode(d, ctx)?),
804 Method::SCREENSHOT => Call::Screenshot(Decode::decode(d, ctx)?),
805 Method::TAP => Call::Tap(Decode::decode(d, ctx)?),
806 Method::SWIPE => Call::Swipe(Decode::decode(d, ctx)?),
807 Method::KEY => Call::Key(Decode::decode(d, ctx)?),
808 Method::TEXT_SET => Call::TextSet(Decode::decode(d, ctx)?),
809 Method::FRAMES_START => Call::FramesStart(Decode::decode(d, ctx)?),
810 Method::FRAMES_STOP => {
811 cbor::skip_map(d)?;
812 Call::FramesStop
813 }
814 Method::RESYNC => Call::Resync(Decode::decode(d, ctx)?),
815 Method::SHUTDOWN => {
816 cbor::skip_map(d)?;
817 Call::Shutdown
818 }
819 Method::BOUNDS => Call::Bounds(Decode::decode(d, ctx)?),
820 other => {
821 d.skip()?;
822 Call::Unknown(other)
823 }
824 })
825 }
826}
827
828impl Reply {
829 pub fn answers(&self, method: Method) -> bool {
831 matches!(
832 (self, method),
833 (Reply::Snapshot(_), Method::SNAPSHOT)
834 | (Reply::Screenshot(_), Method::SCREENSHOT)
835 | (Reply::Input(_), Method::TAP | Method::SWIPE | Method::KEY)
836 | (Reply::Text(_), Method::TEXT_SET)
837 | (Reply::Resync(_), Method::RESYNC)
838 | (Reply::Bounds(_), Method::BOUNDS)
839 | (
840 Reply::Empty,
841 Method::FRAMES_START | Method::FRAMES_STOP | Method::SHUTDOWN
842 )
843 )
844 }
845
846 fn decode_for<'b, C>(
847 method: Method,
848 d: &mut Decoder<'b>,
849 ctx: &mut C,
850 ) -> Result<Reply, decode::Error> {
851 Ok(match method {
852 Method::SNAPSHOT => Reply::Snapshot(Decode::decode(d, ctx)?),
853 Method::SCREENSHOT => Reply::Screenshot(Decode::decode(d, ctx)?),
854 Method::TAP | Method::SWIPE | Method::KEY => Reply::Input(Decode::decode(d, ctx)?),
855 Method::TEXT_SET => Reply::Text(Decode::decode(d, ctx)?),
856 Method::RESYNC => Reply::Resync(Decode::decode(d, ctx)?),
857 Method::BOUNDS => Reply::Bounds(Decode::decode(d, ctx)?),
858 Method::FRAMES_START | Method::FRAMES_STOP | Method::SHUTDOWN => {
859 cbor::skip_map(d)?;
860 Reply::Empty
861 }
862 other => {
863 return Err(decode::Error::message(format!(
864 "a result for {other}, which this version does not know"
865 ))
866 .at(d.position()));
867 }
868 })
869 }
870}
871
872impl<C> Encode<C> for Reply {
873 fn encode<W: Write>(
874 &self,
875 e: &mut Encoder<W>,
876 ctx: &mut C,
877 ) -> Result<(), encode::Error<W::Error>> {
878 match self {
879 Reply::Snapshot(r) => r.encode(e, ctx),
880 Reply::Screenshot(r) => r.encode(e, ctx),
881 Reply::Input(r) => r.encode(e, ctx),
882 Reply::Text(r) => r.encode(e, ctx),
883 Reply::Resync(r) => r.encode(e, ctx),
884 Reply::Bounds(r) => r.encode(e, ctx),
885 Reply::Empty => {
886 e.map(0)?;
887 Ok(())
888 }
889 }
890 }
891}
892
893impl<C> Encode<C> for Response {
894 fn encode<W: Write>(
895 &self,
896 e: &mut Encoder<W>,
897 ctx: &mut C,
898 ) -> Result<(), encode::Error<W::Error>> {
899 e.map(4)?;
900 e.u8(0)?.u8(kind::RESPONSE)?;
901 e.u8(1)?.u32(self.id)?;
902 e.u8(2)?.u16(self.method.0)?;
903 match &self.result {
904 Ok(reply) => {
905 debug_assert!(reply.answers(self.method), "{reply:?} for {}", self.method);
906 e.u8(3)?.encode_with(reply, ctx)?;
907 }
908 Err(error) => {
909 e.u8(4)?.encode_with(error, ctx)?;
910 }
911 }
912 Ok(())
913 }
914}
915
916impl<'b, C> Decode<'b, C> for Response {
917 fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Response, decode::Error> {
918 let at = d.position();
919 let mut k = None;
920 let mut id = None;
921 let mut method = None;
922 let mut result_at = None;
923 let mut error = None;
924 cbor::map_entries(d, |d, key| {
925 match key {
926 0 => k = Some(d.u8()?),
927 1 => id = Some(d.u32()?),
928 2 => method = Some(Method(d.u16()?)),
929 3 => {
931 result_at = Some(d.position());
932 d.skip()?;
933 }
934 4 => error = Option::<Error>::decode(d, &mut *ctx)?,
935 _ => d.skip()?,
936 }
937 Ok(())
938 })?;
939 cbor::expect_kind(k, kind::RESPONSE, at)?;
940 let id = id.ok_or_else(|| cbor::missing(1, "id").at(at))?;
941 let method = method.ok_or_else(|| cbor::missing(2, "method").at(at))?;
942 let result = match (result_at, error) {
943 (Some(result_at), None) => {
944 let mut result = d.clone();
945 result.set_position(result_at);
946 Ok(Reply::decode_for(method, &mut result, ctx)?)
947 }
948 (None, Some(error)) => Err(error),
949 (Some(_), Some(_)) => {
950 return Err(
951 decode::Error::message("a response with both a result and an error").at(at),
952 );
953 }
954 (None, None) => {
955 return Err(decode::Error::message(
956 "a response with neither a result nor an error",
957 )
958 .at(at));
959 }
960 };
961 Ok(Response { id, method, result })
962 }
963}
964
965impl<C> Encode<C> for Ping {
966 fn encode<W: Write>(
967 &self,
968 e: &mut Encoder<W>,
969 _: &mut C,
970 ) -> Result<(), encode::Error<W::Error>> {
971 e.map(2)?.u8(0)?.u8(kind::PING)?.u8(1)?.u64(self.nonce)?;
972 Ok(())
973 }
974}
975
976impl<'b, C> Decode<'b, C> for Ping {
977 fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Ping, decode::Error> {
978 decode_nonce(d, kind::PING).map(|nonce| Ping { nonce })
979 }
980}
981
982impl<C> Encode<C> for Pong {
983 fn encode<W: Write>(
984 &self,
985 e: &mut Encoder<W>,
986 _: &mut C,
987 ) -> Result<(), encode::Error<W::Error>> {
988 e.map(2)?.u8(0)?.u8(kind::PONG)?.u8(1)?.u64(self.nonce)?;
989 Ok(())
990 }
991}
992
993impl<'b, C> Decode<'b, C> for Pong {
994 fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Pong, decode::Error> {
995 decode_nonce(d, kind::PONG).map(|nonce| Pong { nonce })
996 }
997}
998
999fn decode_nonce(d: &mut Decoder<'_>, expected: u8) -> Result<u64, decode::Error> {
1000 let at = d.position();
1001 let mut k = None;
1002 let mut nonce = None;
1003 cbor::map_entries(d, |d, key| {
1004 match key {
1005 0 => k = Some(d.u8()?),
1006 1 => nonce = Some(d.u64()?),
1007 _ => d.skip()?,
1008 }
1009 Ok(())
1010 })?;
1011 cbor::expect_kind(k, expected, at)?;
1012 nonce.ok_or_else(|| cbor::missing(1, "nonce").at(at))
1013}