Preview of the proposed up-rust native-frame-model branch (up-rust b6b99c6d, up-spec f0e9b17) — not released documentation. branch · write-up

up_rust/payload/
mod.rs

1/********************************************************************************
2 * Copyright (c) 2026 Contributors to the Eclipse Foundation
3 *
4 * See the NOTICE file(s) distributed with this work for additional
5 * information regarding copyright ownership.
6 *
7 * This program and the accompanying materials are made available under the
8 * terms of the Apache License Version 2.0 which is available at
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 ********************************************************************************/
13
14use std::{error::Error, fmt::Display};
15
16use crate::{PayloadEncoding, UCode, UStatus};
17
18/// Payload codec traits: measure, encode, and decode typed payloads.
19pub mod codec;
20/// Loan-aware payload construction: write typed payloads into transport storage.
21pub mod loan;
22pub mod stable;
23
24/// Error type used by serialization-neutral payload helpers.
25#[derive(Clone, Debug, Eq, PartialEq)]
26#[non_exhaustive]
27pub enum UWireError {
28    /// A caller-provided output buffer is too small for the serialized payload.
29    BufferTooSmall {
30        /// Required output size in bytes.
31        expected: usize,
32        /// Provided output size in bytes.
33        actual: usize,
34    },
35    /// Payload bytes are malformed for the selected decoder.
36    InvalidPayload(String),
37    /// A typed decode was requested, but the frame has no payload encoding.
38    MissingEncoding,
39    /// A typed decode was requested, but the frame has no payload bytes.
40    MissingPayload,
41    /// The frame's encoding is not compatible with the selected payload codec.
42    UnsupportedEncoding {
43        /// Encoding declared by the requested codec.
44        expected: Box<PayloadEncoding>,
45        /// Encoding carried by the frame being decoded.
46        actual: Box<PayloadEncoding>,
47    },
48    /// Serializer or deserializer implementation failed.
49    SerializationError(String),
50}
51
52impl UWireError {
53    /// Creates a [`UWireError::BufferTooSmall`] value.
54    #[must_use]
55    pub fn buffer_too_small(expected: usize, actual: usize) -> Self {
56        Self::BufferTooSmall { expected, actual }
57    }
58
59    /// Creates a [`UWireError::InvalidPayload`] value.
60    #[must_use]
61    pub fn invalid_payload(message: impl Into<String>) -> Self {
62        Self::InvalidPayload(message.into())
63    }
64
65    /// Creates a stable payload length error.
66    #[must_use]
67    pub fn invalid_payload_length(expected: usize, actual: usize) -> Self {
68        Self::invalid_payload(format!("payload length must be {expected}, got {actual}"))
69    }
70
71    /// Creates a [`UWireError::SerializationError`] value.
72    #[must_use]
73    pub fn serialization_error(message: impl Into<String>) -> Self {
74        Self::SerializationError(message.into())
75    }
76}
77
78impl Display for UWireError {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        match self {
81            Self::BufferTooSmall { expected, actual } => f.write_fmt(format_args!(
82                "buffer too small: expected at least {expected} bytes, got {actual} bytes"
83            )),
84            Self::InvalidPayload(message) => {
85                f.write_fmt(format_args!("invalid payload: {message}"))
86            }
87            Self::MissingEncoding => f.write_str("frame payload has no encoding metadata"),
88            Self::MissingPayload => f.write_str("frame has no payload"),
89            Self::UnsupportedEncoding { expected, actual } => f.write_fmt(format_args!(
90                "unsupported payload encoding: expected {expected:?}; got {actual:?}",
91            )),
92            Self::SerializationError(message) => {
93                f.write_fmt(format_args!("serialization error: {message}"))
94            }
95        }
96    }
97}
98
99impl Error for UWireError {}
100
101impl From<UWireError> for UStatus {
102    fn from(value: UWireError) -> Self {
103        UStatus::fail_with_code(UCode::InvalidArgument, value.to_string())
104    }
105}