Upgrade pdl-runtime to 0.3.0

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/rust/crates/pdl-runtime
For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: I5564500a61183a8cca18aa2fd7d6a8ceb9d1426b
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 @@
     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 @@
   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 @@
 ## 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())
+    }
 }