Skip to main content

zenoh_codec/network/
timestamp_stack.rs

1//
2// Copyright (c) 2026 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 alloc::vec::Vec;
15
16use zenoh_buffers::{
17    reader::{DidntRead, Reader},
18    writer::{DidntWrite, Writer},
19};
20use zenoh_protocol::{
21    common::ZExtZBufHeader,
22    network::timestamp_stack::{Interception, TimestampStack, TsStackType},
23};
24
25use crate::{LCodec, RCodec, WCodec, Zenoh080, Zenoh080Header};
26
27// Interception
28impl LCodec<&Interception> for Zenoh080 {
29    fn w_len(self, x: &Interception) -> usize {
30        1 + self.w_len(&x.timestamp[..])
31    }
32}
33
34impl<W> WCodec<&Interception, &mut W> for Zenoh080
35where
36    W: Writer,
37{
38    type Output = Result<(), DidntWrite>;
39
40    fn write(self, writer: &mut W, x: &Interception) -> Self::Output {
41        self.write(&mut *writer, x.flags)?;
42        self.write(&mut *writer, &x.timestamp[..])
43    }
44}
45
46impl<R> RCodec<Interception, &mut R> for Zenoh080
47where
48    R: Reader,
49{
50    type Error = DidntRead;
51
52    fn read(self, reader: &mut R) -> Result<Interception, Self::Error> {
53        let flags: u8 = self.read(&mut *reader)?;
54        let timestamp: Vec<u8> = self.read(&mut *reader)?;
55        Ok(Interception { flags, timestamp })
56    }
57}
58
59// TimestampStack
60impl LCodec<&TimestampStack> for Zenoh080 {
61    fn w_len(self, x: &TimestampStack) -> usize {
62        let mut len = 1; // conf_flags
63        len += self.w_len(x.stack.len());
64        for i in &x.stack {
65            len += self.w_len(i);
66        }
67        len
68    }
69}
70
71impl<W> WCodec<&TimestampStack, &mut W> for Zenoh080
72where
73    W: Writer,
74{
75    type Output = Result<(), DidntWrite>;
76
77    fn write(self, writer: &mut W, x: &TimestampStack) -> Self::Output {
78        self.write(&mut *writer, x.conf_flags)?;
79        self.write(&mut *writer, x.stack.len())?;
80        for i in &x.stack {
81            self.write(&mut *writer, i)?;
82        }
83        Ok(())
84    }
85}
86
87impl<R> RCodec<TimestampStack, &mut R> for Zenoh080
88where
89    R: Reader,
90{
91    type Error = DidntRead;
92
93    fn read(self, reader: &mut R) -> Result<TimestampStack, Self::Error> {
94        let conf_flags: u8 = self.read(&mut *reader)?;
95        if conf_flags == 0 {
96            // empty conf_flags is invalid
97            return Err(DidntRead);
98        }
99        let count: usize = self.read(&mut *reader)?;
100        if count > zenoh_protocol::network::timestamp_stack::MAX_STACK_SIZE {
101            return Err(DidntRead);
102        }
103        let mut stack: Vec<Interception> = Vec::with_capacity(count);
104        for _ in 0..count {
105            stack.push(self.read(&mut *reader)?);
106        }
107        Ok(TimestampStack { conf_flags, stack })
108    }
109}
110
111// TsStackType extension wrapper
112impl<const ID: u8> LCodec<&TsStackType<{ ID }>> for Zenoh080 {
113    fn w_len(self, x: &TsStackType<{ ID }>) -> usize {
114        self.w_len(&x.ts_stack)
115    }
116}
117
118impl<W, const ID: u8> WCodec<(&TsStackType<{ ID }>, bool), &mut W> for Zenoh080
119where
120    W: Writer,
121{
122    type Output = Result<(), DidntWrite>;
123
124    fn write(self, writer: &mut W, x: (&TsStackType<{ ID }>, bool)) -> Self::Output {
125        let (x, more) = x;
126        let header: ZExtZBufHeader<{ ID }> = ZExtZBufHeader::new(self.w_len(x));
127        self.write(&mut *writer, (&header, more))?;
128        self.write(&mut *writer, &x.ts_stack)
129    }
130}
131
132impl<R, const ID: u8> RCodec<(TsStackType<{ ID }>, bool), &mut R> for Zenoh080
133where
134    R: Reader,
135{
136    type Error = DidntRead;
137
138    fn read(self, reader: &mut R) -> Result<(TsStackType<{ ID }>, bool), Self::Error> {
139        let header: u8 = self.read(&mut *reader)?;
140        let codec = Zenoh080Header::new(header);
141        codec.read(reader)
142    }
143}
144
145impl<R, const ID: u8> RCodec<(TsStackType<{ ID }>, bool), &mut R> for Zenoh080Header
146where
147    R: Reader,
148{
149    type Error = DidntRead;
150
151    fn read(self, reader: &mut R) -> Result<(TsStackType<{ ID }>, bool), Self::Error> {
152        let (_, more): (ZExtZBufHeader<{ ID }>, bool) = self.read(&mut *reader)?;
153        let ts_stack: TimestampStack = self.codec.read(&mut *reader)?;
154        Ok((TsStackType { ts_stack }, more))
155    }
156}