~taiite/protodump

98e41a2c53c26ef6cf5f3494fcc8ba02d57d39ff — Hubert Hirtz 9 days ago 34315d0 master
Separate Type::fmt from Instance::fmt
1 files changed, 37 insertions(+), 31 deletions(-)

M src/types.rs
M src/types.rs => src/types.rs +37 -31
@@ 153,6 153,42 @@ pub struct Type<R> {
/// Pointer type for [Type] used through protodump in order to avoid copies.
pub type TypePtr<R> = Rc<RefCell<Type<R>>>;

impl<R> fmt::Display for Type<R>
where
    R: gimli::Reader,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let name = match &self.name {
            Some(raw_name) => raw_name.to_string_lossy().map_err(|_| fmt::Error)?,
            None => Cow::Borrowed("_UNAMED_"),
        };
        match &self.definition {
            Definition::Base { .. } => write!(f, "{}", name),
            Definition::Enumeration { .. } => write!(f, "enum {}", name),
            Definition::Subroutine {
                return_type,
                parameters,
            } => {
                if let Some(type_) = return_type {
                    let type_ = type_.borrow();
                    write!(f, "{}{}fn(", type_, type_.display_padding())?;
                } else {
                    write!(f, "void fn(")?;
                }
                if let Some(param) = parameters.first() {
                    write!(f, "{}", param.borrow())?;
                    for param in &parameters[1..] {
                        write!(f, ", {}", param.borrow())?;
                    }
                }
                write!(f, ")")
            }
            Definition::Structure { .. } => write!(f, "struct {}", name),
            Definition::Union { .. } => write!(f, "union {}", name),
        }
    }
}

/// Type modifier used in type [Instance]s.
// TODO add fields like pointer size, array count, etc.
#[derive(Copy, Clone, Debug, PartialEq)]


@@ 227,37 263,7 @@ where
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self.underlying {
            Some(underlying) => {
                let underlying = underlying.borrow();
                let name = match &underlying.name {
                    Some(raw_name) => raw_name.to_string_lossy().map_err(|_| fmt::Error)?,
                    None => Cow::Borrowed("_UNAMED_"),
                };
                match &underlying.definition {
                    Definition::Base { .. } => write!(f, "{}", name)?,
                    Definition::Enumeration { .. } => write!(f, "enum {}", name)?,
                    Definition::Subroutine {
                        return_type,
                        parameters,
                    } => {
                        if let Some(type_) = return_type {
                            let type_ = type_.borrow();
                            write!(f, "{}{}fn(", type_, type_.display_padding())?;
                        } else {
                            write!(f, "void fn(")?;
                        }
                        if let Some(param) = parameters.first() {
                            write!(f, "{}", param.borrow())?;
                            for param in &parameters[1..] {
                                write!(f, ", {}", param.borrow())?;
                            }
                        }
                        write!(f, ")")?;
                    }
                    Definition::Structure { .. } => write!(f, "struct {}", name)?,
                    Definition::Union { .. } => write!(f, "union {}", name)?,
                }
            }
            Some(underlying) => underlying.borrow().fmt(f)?,
            None => write!(f, "void")?,
        }
        // TODO don't put space on both end of pointers and refs