rudy_dwarf/parser/
result.rs

1//! Option parser implementation using combinators
2
3use anyhow::Result;
4use rudy_types::ResultLayout;
5
6use super::Parser;
7use crate::{
8    parser::{
9        children::parse_children,
10        combinators::all,
11        enums::{enum_discriminant, enum_named_tuple_variant},
12        primitives::{attr, member_by_tag, resolve_type_shallow},
13    },
14    Die, DwarfDb,
15};
16
17pub struct ResultDefParser;
18
19/// Parser for result types
20///
21/// We'll parse it as a generic enum, and extract out the expect "Ok" and "Err" variants
22pub fn result_def() -> ResultDefParser {
23    ResultDefParser
24}
25
26impl Parser<ResultLayout<Die>> for ResultDefParser {
27    fn parse(&self, db: &dyn DwarfDb, entry: Die) -> Result<ResultLayout<Die>> {
28        tracing::debug!("resolving result type: {}", entry.print(db));
29
30        // Get the variant part
31        let (name, size, (discriminant, (ok, err))) = all((
32            attr::<String>(gimli::DW_AT_name),
33            attr::<usize>(gimli::DW_AT_byte_size),
34            member_by_tag(gimli::DW_TAG_variant_part).then(enum_discriminant().and(
35                parse_children((
36                    enum_named_tuple_variant("Ok", (resolve_type_shallow(),)).map(
37                        |(discriminant, ((ok_offset, ok_type),))| {
38                            (discriminant, (ok_offset, ok_type))
39                        },
40                    ),
41                    enum_named_tuple_variant("Err", (resolve_type_shallow(),)).map(
42                        |(discriminant, ((err_offset, err_type),))| {
43                            (discriminant, (err_offset, err_type))
44                        },
45                    ),
46                )),
47            )),
48        ))
49        .parse(db, entry)?;
50
51        let (_, (ok_offset, ok_type)) = ok;
52        let (_, (err_offset, err_type)) = err;
53
54        Ok(ResultLayout {
55            name,
56            ok_type,
57            ok_offset,
58            err_type,
59            err_offset,
60            size,
61            discriminant,
62        })
63    }
64}