vmcore/
local_only.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Type definitions for types that cannot cross a mesh process boundary.
5
6#![forbid(unsafe_code)]
7
8use mesh::payload::Error;
9use mesh::payload::FieldDecode;
10use mesh::payload::FieldEncode;
11use mesh::payload::inplace::InplaceOption;
12use mesh::payload::protobuf::FieldReader;
13use mesh::payload::protobuf::FieldSizer;
14use mesh::payload::protobuf::FieldWriter;
15use thiserror::Error;
16
17/// A wrapper type that skips serializing the type and fails deserialization.
18/// This allows the type to be used in a MeshPayload derive but will fail when
19/// sent across a process boundary at runtime.
20#[derive(Debug, Clone)]
21pub struct LocalOnly<T>(pub T);
22
23impl<T> mesh::payload::DefaultEncoding for LocalOnly<T> {
24    type Encoding = LocalOnlyField;
25}
26
27/// A field encoder for fields that should be ignored on write and fail on read.
28///
29/// This is useful for enum variants that can't be sent across processes.
30pub struct LocalOnlyField;
31
32/// Error when attempting to deserialize an instance of [`LocalOnly`].
33#[derive(Debug, Error)]
34#[error("decoding local-only type")]
35pub struct LocalOnlyError;
36
37impl<T, R> FieldEncode<T, R> for LocalOnlyField {
38    fn write_field(_item: T, writer: FieldWriter<'_, '_, R>) {
39        tracing::warn!(
40            type_name = std::any::type_name::<T>(),
41            "encoding local-only type"
42        );
43        writer.message(|_| ());
44    }
45
46    fn compute_field_size(_item: &mut T, sizer: FieldSizer<'_>) {
47        sizer.message(|_| ());
48    }
49}
50
51impl<T, R> FieldDecode<'_, T, R> for LocalOnlyField {
52    fn read_field(
53        _item: &mut InplaceOption<'_, T>,
54        _reader: FieldReader<'_, '_, R>,
55    ) -> Result<(), Error> {
56        Err(Error::new(LocalOnlyError))
57    }
58
59    fn default_field(_item: &mut InplaceOption<'_, T>) -> Result<(), Error> {
60        Err(Error::new(LocalOnlyError))
61    }
62}