use std::{io, path::PathBuf};
use thiserror::Error;
#[derive(Error, Debug, Clone)]
pub enum ValueError {
#[error("unknown concept: {concept}")]
UnknownConcept { concept: String },
#[error("missing context reference: {context_ref}")]
MissingContext { context_ref: String },
#[error("missing unit reference: {unit_ref}")]
MissingUnit { unit_ref: String },
#[error("invalid boolean value '{raw}'")]
InvalidBoolean { raw: String },
#[error("invalid integer value '{raw}'")]
InvalidInteger { raw: String },
#[error("invalid decimal value '{raw}'")]
InvalidDecimal { raw: String },
#[error("invalid date value '{raw}'")]
InvalidDate { raw: String },
#[error("invalid dateTime value '{raw}'")]
InvalidDateTime { raw: String },
#[error("invalid QName value '{raw}': {reason}")]
InvalidQName { raw: String, reason: String },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LinkbaseType {
Label,
Presentation,
Calculation,
Definition,
Reference,
}
impl std::fmt::Display for LinkbaseType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LinkbaseType::Label => write!(f, "label"),
LinkbaseType::Presentation => write!(f, "presentation"),
LinkbaseType::Calculation => write!(f, "calculation"),
LinkbaseType::Definition => write!(f, "definition"),
LinkbaseType::Reference => write!(f, "reference"),
}
}
}
#[derive(Error, Debug)]
pub enum XbrlError {
#[error("Error parsing XML at position {position}{}{}: {source}", path.as_ref().map(|path| format!(" in file {}", path.display())).unwrap_or_default(), element.as_ref().map(|err| format!(" in element <{}>", err)).unwrap_or_default())]
XmlParse {
path: Option<PathBuf>,
position: u64,
element: Option<String>,
#[source]
source: quick_xml::Error,
},
#[error("Error parsing {linkbase_type} linkbase{}: {source}", file_path.as_ref().map(|path| format!(" from {}", path.display())).unwrap_or_default())]
LinkbaseParse {
linkbase_type: LinkbaseType,
file_path: Option<PathBuf>,
#[source]
source: quick_xml::Error,
},
#[error("Failed to open file: {}", path.display())]
FileOpen {
path: PathBuf,
#[source]
source: io::Error,
},
#[error("Failed to read file: {}", path.display())]
FileRead {
path: PathBuf,
#[source]
source: io::Error,
},
#[error("Failed to write file: {}", path.display())]
FileWrite {
path: PathBuf,
#[source]
source: io::Error,
},
#[error("{element} missing required attribute: {attribute}")]
MissingAttribute { element: String, attribute: String },
#[error("Failed to discover taxonomy for schema ref '{schema_ref}' with entry point {}", entry_point.display())]
TaxonomyDiscovery {
schema_ref: String,
entry_point: PathBuf,
#[source]
source: Box<XbrlError>,
},
#[error(
"Schema refs have mismatched versions: expected '{expected}', \
found '{found}' in '{schema_ref}'"
)]
VersionMismatch {
expected: String,
found: String,
schema_ref: String,
},
#[error("Invalid XLink href '{href}': {reason}")]
InvalidHref { href: String, reason: String },
#[error("Invalid schema document '{}': {reason}", path.as_ref().map(|path| path.display().to_string()).unwrap_or_else(|| "unknown".to_string()))]
InvalidSchemaDocument {
path: Option<PathBuf>,
reason: String,
},
#[error("Error resolving schema: {reason}")]
InvalidSchemaResolution { reason: String },
#[error("Invalid instance document '{}': {reason}", path.as_ref().map(|path| path.display().to_string()).unwrap_or_else(|| "unknown".to_string()))]
InvalidInstanceDocument {
path: Option<PathBuf>,
reason: String,
},
#[error("Invalid linkbase document '{}': {reason}", path.as_ref().map(|path| path.display().to_string()).unwrap_or_else(|| "unknown".to_string()))]
InvalidLinkbaseDocument {
path: Option<PathBuf>,
reason: String,
},
#[error("Error resolving linkbase: {reason}")]
InvalidLinkbaseResolution { reason: String },
#[error("invalid {expected} value '{value}'")]
ParseError {
expected: &'static str,
value: String,
},
#[error(transparent)]
Value(#[from] ValueError),
#[error(transparent)]
Io(#[from] io::Error),
#[error(transparent)]
Xml(#[from] quick_xml::Error),
#[error(transparent)]
Utf8(#[from] std::str::Utf8Error),
#[error(transparent)]
Escape(#[from] quick_xml::escape::EscapeError),
}
pub type Result<T> = std::result::Result<T, XbrlError>;