aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Duarte <licorne@google.com>2024-06-04 00:34:17 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2024-06-04 00:34:17 +0000
commitae290114b002638ec5694cc0df5abf314c0e6681 (patch)
treeece4849b52cc8838865430cd1b93cc03cdbe3c8e
parentffc075afa2d15884a37b929cd35f1615462b046f (diff)
parent67a386da6a4243f5adf1733bf4c6679169f9d740 (diff)
downloadpdl-runtime-main.tar.gz
Upgrade pdl-runtime to 0.3.0 am: 67a386da6aHEADmastermain
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/pdl-runtime/+/3108708 Change-Id: Id1e82d2a2ab5a754ce8a8a8b79e4db2834dae5bf Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp2
-rw-r--r--Cargo.toml2
-rw-r--r--Cargo.toml.orig2
-rw-r--r--METADATA8
-rw-r--r--README.md2
-rw-r--r--src/lib.rs104
7 files changed, 102 insertions, 20 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index c80110d..d308c05 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "1aca6665980cddba4f12c36b13080694f1d76b4d"
+ "sha1": "4dbe66da6a922c64436a8f3a00a4ab1f0ebafbb6"
},
"path_in_vcs": "pdl-runtime"
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index f1fe3ae..f7bb4b0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -8,7 +8,7 @@ rust_library {
host_supported: true,
crate_name: "pdl_runtime",
cargo_env_compat: true,
- cargo_pkg_version: "0.2.3",
+ cargo_pkg_version: "0.3.0",
crate_root: "src/lib.rs",
edition: "2021",
rustlibs: [
diff --git a/Cargo.toml b/Cargo.toml
index da7d0f1..cd91184 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
[package]
edition = "2021"
name = "pdl-runtime"
-version = "0.2.3"
+version = "0.3.0"
authors = [
"Henri Chataing <henrichataing@google.com>",
"David de Jesus Duarte <licorne@google.com>",
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 986c1c2..e1d300f 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "pdl-runtime"
-version = "0.2.3"
+version = "0.3.0"
edition = "2021"
description = "PDL's runtime library"
repository = "https://github.com/google/pdl/"
diff --git a/METADATA b/METADATA
index d2e51db..daa6821 100644
--- a/METADATA
+++ b/METADATA
@@ -8,13 +8,13 @@ third_party {
license_type: NOTICE
last_upgrade_date {
year: 2024
- month: 2
- day: 5
+ month: 5
+ day: 29
}
identifier {
type: "crates.io"
- value: "https://static.crates.io/crates/pdl-runtime/pdl-runtime-0.2.3.crate"
- version: "0.2.2"
+ value: "https://static.crates.io/crates/pdl-runtime/pdl-runtime-0.3.0.crate"
+ version: "0.3.0"
}
identifier {
type: "Archive"
diff --git a/README.md b/README.md
index 1396b3d..a8e96fc 100644
--- a/README.md
+++ b/README.md
@@ -45,5 +45,5 @@ Language specific instructions are provided for all supported backends:
## Similar projects
- [Kaitai](https://kaitai.io)
-- [EMBOSS](https://github.com/kimrutherford/EMBOSS)
+- [Emboss](https://github.com/google/emboss)
- [P4](https://p4.org/p4-spec/docs/P4-16-v1.0.0-spec.html)
diff --git a/src/lib.rs b/src/lib.rs
index 4e78bf9..32d26dc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,32 +14,114 @@
//! Helper definitions used used by the generated Rust backend.
-use bytes::Bytes;
-use thiserror::Error;
+use bytes::{BufMut, Bytes, BytesMut};
/// Type of parsing errors.
-#[derive(Debug, Error, PartialEq, Eq)]
-pub enum Error {
- #[error("Packet parsing failed")]
+#[derive(Debug, thiserror::Error, PartialEq, Eq)]
+pub enum DecodeError {
+ #[error("packet parsing failed")]
InvalidPacketError,
#[error("{field} was {value:x}, which is not known")]
- ConstraintOutOfBounds { field: String, value: u64 },
+ ConstraintOutOfBounds { field: &'static str, value: u64 },
#[error("Got {actual:x}, expected {expected:x}")]
InvalidFixedValue { expected: u64, actual: u64 },
#[error("when parsing {obj} needed length of {wanted} but got {got}")]
- InvalidLengthError { obj: String, wanted: usize, got: usize },
+ InvalidLengthError { obj: &'static str, wanted: usize, got: usize },
#[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")]
InvalidArraySize { array: usize, element: usize },
#[error("Due to size restrictions a struct could not be parsed.")]
ImpossibleStructError,
#[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")]
- InvalidEnumValueError { obj: String, field: String, value: u64, type_: String },
+ InvalidEnumValueError {
+ obj: &'static str,
+ field: &'static str,
+ value: u64,
+ type_: &'static str,
+ },
+ #[error("invalid field {packet}::{field} value, {expected} != {actual}")]
+ InvalidFieldValue {
+ packet: &'static str,
+ field: &'static str,
+ expected: &'static str,
+ actual: String,
+ },
#[error("expected child {expected}, got {actual}")]
InvalidChildError { expected: &'static str, actual: String },
+ #[error("packet has trailing bytes")]
+ TrailingBytes,
+ #[error("packet has trailing bytes inside {obj}.{field} array")]
+ TrailingBytesInArray { obj: &'static str, field: &'static str },
+}
+
+/// Type of serialization errors.
+#[derive(Debug, thiserror::Error, PartialEq, Eq)]
+pub enum EncodeError {
+ #[error("the size of {packet}::{field} ({size}) is outside the range of valid values 0..{maximum_size}")]
+ SizeOverflow { packet: &'static str, field: &'static str, size: usize, maximum_size: usize },
+ #[error(
+ "the count of {packet}::{field} ({count}) is outside the range of valid values 0..{maximum_count}"
+ )]
+ CountOverflow { packet: &'static str, field: &'static str, count: usize, maximum_count: usize },
+ #[error(
+ "the value of {packet}::{field} ({value}) is outside the range of valid values 0..{maximum_value}"
+ )]
+ InvalidScalarValue { packet: &'static str, field: &'static str, value: u64, maximum_value: u64 },
+ #[error(
+ "{packet}.{field}[{element_index}] size is {size}, but {expected_size} was expected (size of {packet}.{field}[0])"
+ )]
+ InvalidArrayElementSize {
+ packet: &'static str,
+ field: &'static str,
+ size: usize,
+ expected_size: usize,
+ element_index: usize,
+ },
}
/// Trait implemented for all toplevel packet declarations.
-pub trait Packet {
- fn to_bytes(self) -> Bytes;
- fn to_vec(self) -> Vec<u8>;
+pub trait Packet: Sized {
+ /// Try parsing an instance of Self from the input slice.
+ /// On success, returns the parsed object and the remaining unparsed slice.
+ /// On failure, returns an error with the reason for the parsing failure.
+ fn decode(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError>;
+
+ /// Try parsing an instance of Packet updating the slice in place
+ /// to the remainder of the data. The input buffer is not updated if
+ /// parsing fails.
+ fn decode_mut(buf: &mut &[u8]) -> Result<Self, DecodeError> {
+ let (packet, remaining) = Self::decode(buf)?;
+ *buf = remaining;
+ Ok(packet)
+ }
+
+ /// Try parsing an instance of Packet from the input slice.
+ /// Returns an error if unparsed bytes remain at the end of the input slice.
+ fn decode_full(buf: &[u8]) -> Result<Self, DecodeError> {
+ let (packet, remaining) = Self::decode(buf)?;
+ if remaining.is_empty() {
+ Ok(packet)
+ } else {
+ Err(DecodeError::TrailingBytes)
+ }
+ }
+
+ /// Return the length of the encoded packet.
+ fn encoded_len(&self) -> usize;
+
+ /// Write the packet to an output buffer.
+ fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>;
+
+ /// Encode the packet to a byte vector.
+ fn encode_to_vec(&self) -> Result<Vec<u8>, EncodeError> {
+ let mut buf = Vec::with_capacity(self.encoded_len());
+ self.encode(&mut buf)?;
+ Ok(buf)
+ }
+
+ /// Encode the packet to a Bytes object.
+ fn encode_to_bytes(&self) -> Result<Bytes, EncodeError> {
+ let mut buf = BytesMut::with_capacity(self.encoded_len());
+ self.encode(&mut buf)?;
+ Ok(buf.freeze())
+ }
}