zenoh_codec/transport/
close.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14use zenoh_buffers::{
15    reader::{DidntRead, Reader},
16    writer::{DidntWrite, Writer},
17};
18use zenoh_protocol::{
19    common::imsg,
20    transport::{
21        close::{flag, Close},
22        id,
23    },
24};
25
26use crate::{common::extension, RCodec, WCodec, Zenoh080, Zenoh080Header};
27
28impl<W> WCodec<&Close, &mut W> for Zenoh080
29where
30    W: Writer,
31{
32    type Output = Result<(), DidntWrite>;
33
34    fn write(self, writer: &mut W, x: &Close) -> Self::Output {
35        let Close { reason, session } = x;
36
37        // Header
38        let mut header = id::CLOSE;
39        if *session {
40            header |= flag::S;
41        }
42        self.write(&mut *writer, header)?;
43
44        // Body
45        self.write(&mut *writer, reason)?;
46
47        Ok(())
48    }
49}
50
51impl<R> RCodec<Close, &mut R> for Zenoh080
52where
53    R: Reader,
54{
55    type Error = DidntRead;
56
57    fn read(self, reader: &mut R) -> Result<Close, Self::Error> {
58        let header: u8 = self.read(&mut *reader)?;
59        let codec = Zenoh080Header::new(header);
60
61        codec.read(reader)
62    }
63}
64
65impl<R> RCodec<Close, &mut R> for Zenoh080Header
66where
67    R: Reader,
68{
69    type Error = DidntRead;
70
71    fn read(self, reader: &mut R) -> Result<Close, Self::Error> {
72        if imsg::mid(self.header) != id::CLOSE {
73            return Err(DidntRead);
74        }
75        let session = imsg::has_flag(self.header, flag::S);
76
77        // Body
78        let reason: u8 = self.codec.read(&mut *reader)?;
79
80        // Extensions
81        let has_ext = imsg::has_flag(self.header, flag::Z);
82        if has_ext {
83            extension::skip_all(reader, "Close")?;
84        }
85
86        Ok(Close { reason, session })
87    }
88}