aboutsummaryrefslogblamecommitdiffstats
path: root/src/error.rs
blob: ae4aa268d2103b3fa90df334bd1c965116ff7221 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                     
        
                       
                   
              
  
 

                     



                                                   
 
                              
                           
                                                               
                    
                                           
                                                
                                                 
                                         
                                         
                           






                                                                               
                 
                                                   
                 


                                                                                     



                                                  

 
                                               
                              
                



                                    
                                 
                                
                       
                                                    
                               
                                                

                                                      
                                                        
                                        
                               
                                                                   
                                 
                                            
                         
                                                                       
                      
                                                                
                                
                                          
                                          
                                                             
                     

 






                                        
                       
                                




                                                         
 
use std::{
    collections::{HashMap, VecDeque},
    fmt,
    num::ParseIntError,
    str::Utf8Error,
    sync::Arc,
};

use thiserror::Error;

use crate::{
    element::{Content, Name, NamespaceDeclaration},
    Element,
};

#[derive(Error, Debug, Clone)]
pub enum DeserializeError {
    #[error("could not parse string {0:?} to requested value")]
    FromStr(String),
    #[error("unexpected attributes {0:?}")]
    UnexpectedAttributes(HashMap<Name, String>),
    #[error("unexpected element content: {0:?}")]
    UnexpectedContent(VecDeque<Content>),
    #[error("attribute `{0:?}` missing")]
    MissingAttribute(Name),
    #[error("incorrect localname: expected `{expected:?}`, found `{found:?}`")]
    IncorrectName { expected: String, found: String },
    #[error("incorrect namespace: expected `{expected:?}`, found `{found:?}`")]
    IncorrectNamespace { expected: String, found: String },
    #[error("unqualified namespace: expected `{expected:?}`")]
    Unqualified { expected: String },
    #[error("element missing expected child")]
    MissingChild,
    #[error("element missing expected text value")]
    MissingValue,
    // not used by crate (yet), but may be used by consumers implementing FromElement
    #[error("unexpected element: {0:?}")]
    UnexpectedElement(Element),
    #[error("attribute `{0}` is an empty string")]
    AttributeEmptyString(String),
    #[error("empty string")]
    EmptyString,
}

// TODO: add error context (usually the stanza)
#[derive(Error, Debug, Clone)]
pub enum Error {
    #[error("io: {0}")]
    // TODO: is this okay?
    ReadError(Arc<std::io::Error>),
    #[error("utf8 conversion: {0}")]
    Utf8Error(#[from] Utf8Error),
    #[error("nom parsing: {0}")]
    ParseError(String),
    #[error("unknown xml entity reference `&{0};`")]
    EntityProcessError(String),
    #[error("invalid character reference: {0}")]
    InvalidCharRef(CharRefError),
    #[error("duplicate namespace declaration: {0:?}")]
    DuplicateNameSpaceDeclaration(NamespaceDeclaration),
    #[error("duplicate attribute: {0}")]
    DuplicateAttribute(String),
    #[error("mismatched end tag: expected `{0:?}`, found `{1:?}`")]
    MismatchedEndTag(Name, Name),
    #[error("not currently in any element")]
    NotInElement(String),
    #[error("extra unexpected data included in complete parse: `{0}`")]
    ExtraData(String),
    #[error("namespace `{0}` has not previously been declared")]
    UndeclaredNamespace(String),
    #[error("deserialization error: {0}")]
    Deserialize(#[from] DeserializeError),
    #[error("root element has already been fully processed")]
    RootElementEnded,
}

impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Self {
        Self::ReadError(Arc::new(e))
    }
}

#[derive(Error, Debug, Clone)]
pub enum CharRefError {
    #[error("int parsing: {0}")]
    ParseInt(#[from] ParseIntError),
    #[error("u32 `{0}` does not represent a valid char")]
    IntegerNotAChar(u32),
    #[error("`{0}` is not a valid xml char")]
    InvalidXMLChar(char),
}