Skip to main content

mapped_vmo/
truncated_immutable.rs

1// Copyright 2026 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
5/// Provides a safe truncated byte slice view of a VMO via a `Deref<Target=[u8]>` implementation.
6#[derive(Debug)]
7pub struct TruncatedImmutableMapping {
8    mapping: crate::ImmutableMapping,
9    len: usize,
10}
11
12impl TruncatedImmutableMapping {
13    /// Maps the `vmo` with [`crate::ImmutableMapping::create_from_vmo`].
14    ///
15    /// The slice returned by the `Deref` implementation will be truncated to `len` instead of the
16    /// size of `vmo`.
17    ///
18    /// Errors if `len` is longer than the size of `vmo`.
19    pub fn create_from_vmo(
20        vmo: &zx::Vmo,
21        immediately_page: bool,
22        len: usize,
23    ) -> Result<Self, Error> {
24        let mapping = crate::ImmutableMapping::create_from_vmo(vmo, immediately_page)?;
25        if mapping.len() < len {
26            return Err(Error::VmoSmallerThanLen { vmo_len: mapping.len(), truncated_len: len });
27        }
28        Ok(Self { mapping, len })
29    }
30}
31
32impl std::ops::Deref for TruncatedImmutableMapping {
33    type Target = [u8];
34    fn deref(&self) -> &Self::Target {
35        &self.mapping[..self.len]
36    }
37}
38
39/// Error type for `TruncatedImmutableMapping::create_from_vmo`.
40#[allow(missing_docs)]
41#[derive(thiserror::Error, Debug)]
42pub enum Error {
43    #[error("failed to create immutable mapping")]
44    CreateImmutableMapping(#[from] crate::ImmutableMappingError),
45
46    #[error("the VMO is smaller than the requested len, {vmo_len} < {truncated_len}")]
47    VmoSmallerThanLen { vmo_len: usize, truncated_len: usize },
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn validates_len() {
56        let vmo = zx::Vmo::create(1).unwrap();
57        let too_long = vmo.get_size().unwrap() + 1;
58        std::assert_matches!(
59            TruncatedImmutableMapping::create_from_vmo(&vmo, false, too_long.try_into().unwrap()),
60            Err(Error::VmoSmallerThanLen { .. })
61        );
62    }
63
64    #[test]
65    fn respects_len() {
66        let vmo = zx::Vmo::create(30).unwrap();
67        let () = vmo.write(b"the-content", 0).unwrap();
68
69        let mapping = TruncatedImmutableMapping::create_from_vmo(&vmo, false, 3).unwrap();
70
71        assert_eq!(&mapping[..], b"the");
72    }
73}