Skip to content
This repository was archived by the owner on Nov 7, 2022. It is now read-only.
This repository was archived by the owner on Nov 7, 2022. It is now read-only.

How to use inside functions that return anyhow::Result (or eyre::Result)? #1

@fanninpm

Description

@fanninpm

Problem

Currently, the Error enum does not work well if you want to write a function like this:

use std::path::Path;

use anyhow::Result;  // use eyre::Result;
use xml_doc::{Document, Node};

fn parse_and_remove_non_conf(p: &str) -> Result<()> {
    let xml_file = Path::new(p);
    let mut doc = Document::parse_file(&xml_file)?;
    let root = doc.root_element()?;
    let to_remove: Vec<usize> = root.children(&doc)
        .iter()
        .enumerate()
        .filter_map(|(i, node)| {
            if let Node::Element(elem) = node {
                if elem.name(&doc) == "conf" {
                    return None
                }
            }
            Some(i)
        })
        .collect();
    for i in to_remove.iter().rev() {
        root.remove_child(&mut doc, *i);
    }
    doc.write_file(&xml_file);
    Ok(())
}

Workaround for users

I had to insert this "adapter" in my code (I'm using thiserror):

#[derive(Debug, thiserror::Error)]
enum XmlParseError {
    #[error("no child elements match condition: {cond:?}")]
    MissingChild { cond: String },

    #[error("too many child elements match condition: {cond:?}")]
    ExtraChildren { cond: String },

    #[error("missing attribute: {attr:?}")]
    MissingAttr { attr: String },
}

#[derive(Debug, thiserror::Error)]
enum XmlDocAdapterError {
    #[error("IO Error: {0:?}")]
    Io(std::io::Error),

    #[error("Decoding Error")]
    CannotDecode,

    #[error("{0}")]
    MalformedXml(String),

    #[error("Attempted to move a container element to another parent")]
    ContainerCannotMove,

    #[error("Element already has a parent and needs to be detatched")]
    HasAParent,
}

impl From<xml_doc::Error> for XmlDocAdapterError {
    fn from(err: xml_doc::Error) -> Self {
        match err {
            xml_doc::Error::Io(io_error) => Self::Io(io_error),
            xml_doc::Error::CannotDecode => Self::CannotDecode,
            xml_doc::Error::MalformedXML(s) => Self::MalformedXml(s),
            xml_doc::Error::ContainerCannotMove => Self::ContainerCannotMove,
            xml_doc::Error::HasAParent => Self::HasAParent,
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions