fidl_fuchsia_pkg_ext/
measure.rs

1// Copyright 2020 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 fidl_fuchsia_pkg as fidl;
6
7/// FIDL types that can have their in-line and out-of-line message byte payload size measured.
8pub trait Measurable {
9    /// Determine the message byte count for this instance.
10    fn measure(&self) -> usize;
11}
12
13impl Measurable for fidl::BlobId {
14    fn measure(&self) -> usize {
15        measure_fuchsia_pkg::Measurable::measure(self).num_bytes
16    }
17}
18
19impl Measurable for fidl::BlobInfo {
20    fn measure(&self) -> usize {
21        measure_fuchsia_pkg::Measurable::measure(self).num_bytes
22    }
23}
24
25impl Measurable for fidl::PackageIndexEntry {
26    fn measure(&self) -> usize {
27        measure_fuchsia_pkg::Measurable::measure(self).num_bytes
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34    use proptest::prelude::*;
35
36    /// Truncates `s` to be at most `max_len` bytes.
37    fn truncate_str(s: &str, max_len: usize) -> &str {
38        if s.len() <= max_len {
39            return s;
40        }
41        // TODO(https://github.com/rust-lang/rust/issues/93743): Use floor_char_boundary when stable.
42        let mut index = max_len;
43        while index > 0 && !s.is_char_boundary(index) {
44            index -= 1;
45        }
46        &s[..index]
47    }
48
49    prop_compose! {
50        fn arb_package_index_entry()(
51            url in ".{0,2048}",
52            blob_id: crate::BlobId,
53        ) -> fidl::PackageIndexEntry {
54            // The regex accepts up to 2048 Unicode code points, but the max
55            // length from FIDL is in terms of bytes, not code points.
56            let url = truncate_str(&url, 2048).to_owned();
57            fidl::PackageIndexEntry {
58                package_url: fidl::PackageUrl { url, },
59                meta_far_blob_id: blob_id.into(),
60            }
61        }
62    }
63
64    proptest! {
65        #![proptest_config(ProptestConfig{
66            // Disable persistence to avoid the warning for not running in the
67            // source code directory (since we're running on a Fuchsia target)
68            failure_persistence: None,
69            .. ProptestConfig::default()
70        })]
71
72        #[test]
73        fn blob_id_size_is_as_bytes_size(item: crate::BlobId) {
74            let item: fidl::BlobId = item.into();
75
76            let expected = std::mem::size_of_val(&item);
77            let actual = item.measure();
78            prop_assert_eq!(expected, actual);
79        }
80
81        #[test]
82        fn blob_info_size_is_as_bytes_size(item: crate::BlobInfo) {
83            let item: fidl::BlobInfo = item.into();
84
85            let expected = std::mem::size_of_val(&item);
86            let actual = item.measure();
87            prop_assert_eq!(expected, actual);
88        }
89
90        #[test]
91        fn package_index_entry_size_is_fidl_encoded_size(
92            item in arb_package_index_entry()
93        ) {
94            let actual = item.measure();
95            let (bytes, _) =
96                ::fidl::standalone_encode_value(&item).unwrap();
97            let expected = bytes.len();
98            prop_assert_eq!(expected, actual);
99        }
100    }
101}