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
27impl<T> From<T> for LocalOnly<T> {
28    fn from(value: T) -> Self {
29        LocalOnly(value)
30    }
31}
32
33/// A field encoder for fields that should be ignored on write and fail on read.
34///
35/// This is useful for enum variants that can't be sent across processes.
36pub struct LocalOnlyField;
37
38/// Error when attempting to deserialize an instance of [`LocalOnly`].
39#[derive(Debug, Error)]
40#[error("decoding local-only type")]
41pub struct LocalOnlyError;
42
43impl<T, R> FieldEncode<T, R> for LocalOnlyField {
44    fn write_field(_item: T, writer: FieldWriter<'_, '_, R>) {
45        tracing::warn!(
46            type_name = std::any::type_name::<T>(),
47            "encoding local-only type"
48        );
49        writer.message(|_| ());
50    }
51
52    fn compute_field_size(_item: &mut T, sizer: FieldSizer<'_>) {
53        sizer.message(|_| ());
54    }
55}
56
57impl<T, R> FieldDecode<'_, T, R> for LocalOnlyField {
58    fn read_field(
59        _item: &mut InplaceOption<'_, T>,
60        _reader: FieldReader<'_, '_, R>,
61    ) -> Result<(), Error> {
62        Err(Error::new(LocalOnlyError))
63    }
64
65    fn default_field(_item: &mut InplaceOption<'_, T>) -> Result<(), Error> {
66        Err(Error::new(LocalOnlyError))
67    }
68}