fidl_codec/
util.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::error::{Error, Result};
6
7const ENCODE_RECURSION_LIMIT: usize = 32;
8
9/// How much to add to a size to pad it to a multiple of 8
10pub(crate) fn alignment_padding_for_size(sz: usize) -> usize {
11    // Saturating ops prevent an overflow. The result is probably wrong
12    // afterward but if an object is about to overflow a usize we're probably
13    // gonna fail soon. This just gives the more sophisticated code upstairs
14    // time to notice.
15    ((sz.saturating_add(7usize)) & !7usize).saturating_sub(sz)
16}
17
18/// Tag for a FIDL message to identify it as a request or a response.
19pub(crate) enum Direction {
20    Request,
21    Response,
22}
23
24impl std::string::ToString for Direction {
25    fn to_string(&self) -> String {
26        match self {
27            Direction::Request => "request",
28            Direction::Response => "response",
29        }
30        .to_owned()
31    }
32}
33
34/// Helper object for counting recursion level.
35#[derive(Copy, Clone)]
36pub(crate) struct RecursionCounter(usize);
37
38impl RecursionCounter {
39    /// Create a new recursion counter.
40    pub fn new() -> Self {
41        Self(0)
42    }
43
44    /// Create a new recursion counter from this one with one more level of
45    /// recursion recorded. Duplicating the counter and keeping the old one
46    /// around means you can "decrement" by just throwing away the new counter
47    /// and going back to the old one. The resulting usage pattern is an
48    /// RAII-style frame guard.
49    pub fn next(&self) -> Result<Self> {
50        if self.0 == ENCODE_RECURSION_LIMIT {
51            Err(Error::RecursionLimitExceeded)
52        } else {
53            Ok(Self(self.0 + 1))
54        }
55    }
56}