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

Commit 88f25089 authored by Martin Geisler's avatar Martin Geisler
Browse files

pdl: Avoid unwrap when parsing arrays

Because https://doc.rust-lang.org/std/array/fn.try_from_fn.html is not
yet stable, we do this by collecting the intermediate values into a
Vec, which we turn into an array.

Alternatives would be to emit an array literal (can be a lot more
code), use MaybeUninit (unsafe, can leak memory) or to let all structs
and enums implement Default (extra code, need to pick a default for
enums).

The generated test files now have 94 explicit unwraps. They are all
due to the API and the way it emulates inheritance and OOP.

Tag: #feature
Bug: 279758009
Test: atest pdl_tests pdl_rust_generator_tests_{le,be} pdl_generated_files_compile
Change-Id: I84a780d703079940642664e462deadd8ed335ec6
parent 311a6872
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -345,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)) => {
@@ -384,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)) => {
+13 −9
Original line number Diff line number Diff line
@@ -127,16 +127,20 @@ impl BarData {
                got: bytes.get().remaining(),
            });
        }
        let x = [0; 5].map(|_| {
            Foo::try_from(bytes.get_mut().get_uint(3) as u32)
                .map_err(|_| Error::InvalidEnumValueError {
        let x = (0..5)
            .map(|_| {
                Foo::try_from(bytes.get_mut().get_uint(3) as u32).map_err(|_| {
                    Error::InvalidEnumValueError {
                        obj: "Bar".to_string(),
                        field: String::new(),
                        value: 0,
                        type_: "Foo".to_string(),
                    }
                })
                .unwrap()
        });
            })
            .collect::<Result<Vec<_>>>()?
            .try_into()
            .map_err(|_| Error::InvalidPacketError)?;
        Ok(Self { x })
    }
    fn write_to(&self, buffer: &mut BytesMut) {
+13 −9
Original line number Diff line number Diff line
@@ -127,16 +127,20 @@ impl BarData {
                got: bytes.get().remaining(),
            });
        }
        let x = [0; 5].map(|_| {
            Foo::try_from(bytes.get_mut().get_uint_le(3) as u32)
                .map_err(|_| Error::InvalidEnumValueError {
        let x = (0..5)
            .map(|_| {
                Foo::try_from(bytes.get_mut().get_uint_le(3) as u32).map_err(|_| {
                    Error::InvalidEnumValueError {
                        obj: "Bar".to_string(),
                        field: String::new(),
                        value: 0,
                        type_: "Foo".to_string(),
                    }
                })
                .unwrap()
        });
            })
            .collect::<Result<Vec<_>>>()?
            .try_into()
            .map_err(|_| Error::InvalidPacketError)?;
        Ok(Self { x })
    }
    fn write_to(&self, buffer: &mut BytesMut) {
+5 −1
Original line number Diff line number Diff line
@@ -80,7 +80,11 @@ impl FooData {
                got: bytes.get().remaining(),
            });
        }
        let x = [0; 5].map(|_| Ok::<_, Error>(bytes.get_mut().get_uint(3) as u32).unwrap());
        let x = (0..5)
            .map(|_| Ok::<_, Error>(bytes.get_mut().get_uint(3) as u32))
            .collect::<Result<Vec<_>>>()?
            .try_into()
            .map_err(|_| Error::InvalidPacketError)?;
        Ok(Self { x })
    }
    fn write_to(&self, buffer: &mut BytesMut) {
+5 −1
Original line number Diff line number Diff line
@@ -80,7 +80,11 @@ impl FooData {
                got: bytes.get().remaining(),
            });
        }
        let x = [0; 5].map(|_| Ok::<_, Error>(bytes.get_mut().get_uint_le(3) as u32).unwrap());
        let x = (0..5)
            .map(|_| Ok::<_, Error>(bytes.get_mut().get_uint_le(3) as u32))
            .collect::<Result<Vec<_>>>()?
            .try_into()
            .map_err(|_| Error::InvalidPacketError)?;
        Ok(Self { x })
    }
    fn write_to(&self, buffer: &mut BytesMut) {
Loading