use super::{
super::{data::*, store::*},
invalid_value::*,
};
use {
depiction::*,
kutil::std::{collections::*, error::*, iter::*},
std::io,
thiserror::*,
};
#[derive(Debug, Depict, Error)]
pub enum FloriaError {
#[error("instantiation: {0}")]
Instantiation(String),
#[error("invalid value: {0}")]
#[depict(as(depict))]
InvalidValue(#[from] InvalidValueError),
#[error("store: {0}")]
#[depict(as(depict))]
Store(#[from] StoreError),
#[cfg(feature = "plugins")]
#[error("plugin: {0}")]
#[depict(as(depict))]
Plugin(#[from] super::super::plugins::PluginError),
}
impl FloriaError {
pub fn id(&self) -> Option<ID> {
match self {
Self::Instantiation(_) | Self::Store(_) => None,
Self::InvalidValue(invalid_value) => Some(invalid_value.id.clone()),
#[cfg(feature = "plugins")]
Self::Plugin(plugin) => match plugin {
super::super::plugins::PluginError::Dispatch(dispatch) => Some(dispatch.id()),
_ => None,
},
}
}
}
pub trait FloriaErrors {
fn to_depict(&self, heading: &str) -> DepictFloriaErrors<'_>;
}
impl FloriaErrors for Errors<FloriaError> {
fn to_depict(&self, heading: &str) -> DepictFloriaErrors<'_> {
DepictFloriaErrors { heading: heading.into(), errors: self }
}
}
pub struct DepictFloriaErrors<'own> {
heading: String,
errors: &'own Errors<FloriaError>,
}
impl<'own> Depict for DepictFloriaErrors<'own> {
fn depict<WriteT>(&self, writer: &mut WriteT, context: &DepictionContext) -> io::Result<()>
where
WriteT: io::Write,
{
context.theme.write_heading(writer, &self.heading)?;
let mut table = FastHashMap::<_, Vec<_>>::default();
for error in self.errors {
let id = error.id();
match table.get_mut(&id) {
Some(list) => list.push(error),
None => {
let mut list = Vec::default();
list.push(error);
table.insert(id, list);
}
}
}
for (id, list) in table {
context.indent(writer)?;
match id {
Some(id) => {
id.kind.depict(writer, context)?;
write!(writer, " ")?;
id.depict(writer, context)?;
}
None => {
context.theme.write_meta(writer, "general")?;
}
}
for (error, last) in IterateWithLast::new(list) {
context.indent_into_branch(writer, last)?;
error.depict(
writer,
&context
.child()
.with_separator(false)
.increase_indentation_branch(last)
.with_configuration("variant", "false"),
)?;
}
}
Ok(())
}
}