Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abe848d3 authored by Martin Geisler's avatar Martin Geisler Committed by Android (Google) Code Review
Browse files

Merge changes from topic "cherrypicker-L76600000960405157:N45800001364684986" into tm-mainline-prod

* changes:
  pdl: Avoid unwrap when parsing arrays
  pdl: Propagate child errors from Packet::new
  pdl: Propagate parse errors to callers
  pdl: Use explicit type when converting enum value
  pdl: Make primite enums repr(u64) again
parents 9d91b513 5cbc0aee
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -565,9 +565,9 @@ fn generate_packet_decl(
            )*

            impl TryFrom<#top_level_packet> for #id_packet {
                type Error = TryFromError;
                fn try_from(packet: #top_level_packet) -> std::result::Result<#id_packet, TryFromError> {
                    #id_packet::new(packet.#top_level_id_lower).map_err(TryFromError)
                type Error = Error;
                fn try_from(packet: #top_level_packet) -> Result<#id_packet> {
                    #id_packet::new(packet.#top_level_id_lower)
                }
            }
        }
@@ -634,17 +634,19 @@ fn generate_packet_decl(

            fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result<Self> {
                let data = #top_level_data::parse_inner(&mut bytes)?;
                Ok(Self::new(Arc::new(data)).unwrap())
                Self::new(Arc::new(data))
            }

            #specialize

            fn new(#top_level_id_lower: Arc<#top_level_data>)
                   -> std::result::Result<Self, &'static str> {
            fn new(#top_level_id_lower: Arc<#top_level_data>) -> Result<Self> {
                #(
                    let #parent_shifted_lower_ids = match &#parent_lower_ids.child {
                        #parent_data_child::#parent_shifted_ids(value) => value.clone(),
                        _ => return Err("Could not parse data, wrong child type"),
                        _ => return Err(Error::InvalidChildError {
                            expected: stringify!(#parent_data_child::#parent_shifted_ids),
                            actual: format!("{:?}", &#parent_lower_ids.child),
                        }),
                    };
                )*
                Ok(Self { #(#parent_lower_ids),* })
@@ -770,6 +772,7 @@ fn generate_enum_decl(
    // Generate the variant cases for the enum declaration.
    // Tags declared in ranges are flattened in the same declaration.
    let use_variant_values = is_primitive && (is_complete || !open);
    let repr_u64 = use_variant_values.then(|| quote! { #[repr(u64)] });
    let mut variants = vec![];
    for tag in tags.iter() {
        match tag {
@@ -857,6 +860,7 @@ fn generate_enum_decl(
    let derived_into_types = derived_signed_into_types.chain(derived_unsigned_into_types);

    quote! {
        #repr_u64
        #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
        #[cfg_attr(feature = "serde", serde(try_from = #backing_type_str, into = #backing_type_str))]
+22 −7
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ impl<'a> FieldParser<'a> {
                    let enum_id = format_ident!("{enum_id}");
                    let tag_id = format_ident!("{}", tag_id.to_upper_camel_case());
                    quote! {
                        if #v != #enum_id::#tag_id.into()  {
                        if #v != #value_type::from(#enum_id::#tag_id)  {
                            return Err(Error::InvalidFixedValue {
                                expected: #value_type::from(#enum_id::#tag_id) as u64,
                                actual: #v as u64,
@@ -167,12 +167,19 @@ impl<'a> FieldParser<'a> {
                    }
                }
                ast::FieldDesc::Typedef { id, type_id } => {
                    // TODO(mgeisler): Remove the `unwrap` from the
                    // generated code and return the error to the
                    // caller.
                    let field_name = id;
                    let type_name = type_id;
                    let packet_name = &self.packet_name;
                    let id = format_ident!("{id}");
                    let type_id = format_ident!("{type_id}");
                    quote! { let #id = #type_id::try_from(#v).unwrap(); }
                    quote! {
                        let #id = #type_id::try_from(#v).map_err(|_| Error::InvalidEnumValueError {
                            obj: #packet_name.to_string(),
                            field: #field_name.to_string(),
                            value: #v as u64,
                            type_: #type_name.to_string(),
                        })?;
                    }
                }
                ast::FieldDesc::Reserved { .. } => {
                    if single_value {
@@ -338,7 +345,11 @@ impl<'a> FieldParser<'a> {
                    // TODO(mgeisler): use
                    // https://doc.rust-lang.org/std/array/fn.try_from_fn.html
                    // when stabilized.
                    let #id = [0; #count].map(|_| #parse_element.unwrap());
                    let #id = (0..#count)
                        .map(|_| #parse_element)
                        .collect::<Result<Vec<_>>>()?
                        .try_into()
                        .map_err(|_| Error::InvalidPacketError)?;
                });
            }
            (ElementWidth::Unknown, ArrayShape::CountField(count_field)) => {
@@ -377,7 +388,11 @@ impl<'a> FieldParser<'a> {
                    // TODO(mgeisler): use
                    // https://doc.rust-lang.org/std/array/fn.try_from_fn.html
                    // when stabilized.
                    let #id = [0; #count].map(|_| #parse_element.unwrap());
                    let #id = (0..#count)
                        .map(|_| #parse_element)
                        .collect::<Result<Vec<_>>>()?
                        .try_into()
                        .map_err(|_| Error::InvalidPacketError)?;
                });
            }
            (ElementWidth::Static(_), ArrayShape::CountField(count_field)) => {
+2 −6
Original line number Diff line number Diff line
@@ -82,15 +82,11 @@ pub fn generate(path: &Path) -> String {
            ImpossibleStructError,
            #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")]
            InvalidEnumValueError { obj: String, field: String, value: u64, type_: String },
            #[error("expected child {expected}, got {actual}")]
            InvalidChildError { expected: &'static str, actual: String },
        }
    });

    code.push_str(&quote_block! {
        #[derive(Debug, Error)]
        #[error("{0}")]
        pub struct TryFromError(&'static str);
    });

    code.push_str(&quote_block! {
        pub trait Packet {
            fn to_bytes(self) -> Bytes;
+4 −4
Original line number Diff line number Diff line
@@ -38,17 +38,16 @@ pub enum Error {
    ImpossibleStructError,
    #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")]
    InvalidEnumValueError { obj: String, field: String, value: u64, type_: String },
    #[error("expected child {expected}, got {actual}")]
    InvalidChildError { expected: &'static str, actual: String },
}

#[derive(Debug, Error)]
#[error("{0}")]
pub struct TryFromError(&'static str);

pub trait Packet {
    fn to_bytes(self) -> Bytes;
    fn to_vec(self) -> Vec<u8>;
}

#[repr(u64)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))]
@@ -187,6 +186,7 @@ impl From<IncompleteTruncatedWithRange> for u64 {
    }
}

#[repr(u64)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))]
+4 −4
Original line number Diff line number Diff line
@@ -38,17 +38,16 @@ pub enum Error {
    ImpossibleStructError,
    #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")]
    InvalidEnumValueError { obj: String, field: String, value: u64, type_: String },
    #[error("expected child {expected}, got {actual}")]
    InvalidChildError { expected: &'static str, actual: String },
}

#[derive(Debug, Error)]
#[error("{0}")]
pub struct TryFromError(&'static str);

pub trait Packet {
    fn to_bytes(self) -> Bytes;
    fn to_vec(self) -> Vec<u8>;
}

#[repr(u64)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))]
@@ -187,6 +186,7 @@ impl From<IncompleteTruncatedWithRange> for u64 {
    }
}

#[repr(u64)]
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))]
Loading