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}