elementtree 1.2.3

Parse an XML file into Python elementtree like structure
Documentation
use std::char;

use crate::xml::common::{is_name_char, is_name_start_char, is_whitespace_str};
use crate::xml::reader::lexer::Token;
use crate::xml::reader::parser::{ParserOutcome, PullParser, State};

impl PullParser {
    pub fn inside_reference(&mut self, t: Token, prev_st: State) -> Option<ParserOutcome> {
        match t {
            Token::Character(c)
                if !self.data.ref_data.is_empty() && is_name_char(c)
                    || self.data.ref_data.is_empty() && (is_name_start_char(c) || c == '#') =>
            {
                self.data.ref_data.push(c);
                None
            }

            Token::ReferenceEnd => {
                // TODO: check for unicode correctness
                let name = self.data.take_ref_data();
                let name_len = name.len(); // compute once
                let c = match &name[..] {
                    "lt" => Ok('<'.to_string()),
                    "gt" => Ok('>'.to_string()),
                    "amp" => Ok('&'.to_string()),
                    "apos" => Ok('\''.to_string()),
                    "quot" => Ok('"'.to_string()),
                    "" => Err(self_error!(self; "Encountered empty entity")),
                    _ if name_len > 2 && name.starts_with("#x") => {
                        let num_str = &name[2..name_len];
                        if num_str == "0" {
                            Err(self_error!(self; "Null character entity is not allowed"))
                        } else {
                            match u32::from_str_radix(num_str, 16)
                                .ok()
                                .and_then(char::from_u32)
                            {
                                Some(c) => Ok(c.to_string()),
                                None => Err(
                                    self_error!(self; "Invalid hexadecimal character number in an entity: {}", name),
                                ),
                            }
                        }
                    }
                    _ if name_len > 1 && name.starts_with('#') => {
                        let num_str = &name[1..name_len];
                        if num_str == "0" {
                            Err(self_error!(self; "Null character entity is not allowed"))
                        } else {
                            match num_str.parse::<u32>().ok().and_then(char::from_u32) {
                                Some(c) => Ok(c.to_string()),
                                None => Err(
                                    self_error!(self; "Invalid decimal character number in an entity: {}", name),
                                ),
                            }
                        }
                    }
                    _ => {
                        if let Some(v) = self.config.extra_entities.get(&name) {
                            Ok(v.clone())
                        } else {
                            Err(self_error!(self; "Unexpected entity: {}", name))
                        }
                    }
                };
                match c {
                    Ok(c) => {
                        self.buf.push_str(&c);
                        if prev_st == State::OutsideTag && !is_whitespace_str(&c) {
                            self.inside_whitespace = false;
                        }
                        self.as_state_continue(prev_st)
                    }
                    Err(e) => Some(e),
                }
            }

            _ => Some(self_error!(self; "Unexpected token inside an entity: {}", t)),
        }
    }
}