use crate::Context;
use crate::WarningKind;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Warning {
pub kind: WarningKind,
pub context: Option<Context>,
pub referent: Option<Context>,
}
impl Warning {
pub fn new<T: Into<Context>>(kind: WarningKind, context: Option<T>) -> Self {
Warning {
kind,
context: context.map(|c| c.into()),
referent: None,
}
}
pub fn has_referent(&self) -> bool {
self.referent.is_some()
}
pub fn get_referent(&self) -> Option<&Context> {
self.referent.as_ref()
}
pub fn set_referent<T: Into<Context>>(&mut self, referent: T) {
self.referent = Some(referent.into());
}
pub fn with_referent<T: Into<Context>>(mut self, referent: T) -> Self {
self.set_referent(referent.into());
self
}
}
#[cfg(feature = "issue-names")]
impl Warning {
pub fn get_name(&self) -> &str {
self.kind.get_name()
}
}
impl std::fmt::Display for Warning {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let cause = if self.has_referent() {
let p: crate::PartialContext = self.get_referent().unwrap().clone().into();
format!(", caused by: {}", p)
} else {
String::new()
};
write!(f, "{} at {:?}{}", self.kind, self.context, cause)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::FullContext;
#[test]
fn incremental() {
let context: Context = FullContext::from(None, "[[".to_string()).into();
let mut warning = Warning::new(WarningKind::UnclosedLink, Some(context));
assert!(!warning.has_referent());
assert!(warning.get_referent().is_none());
let ref_context = FullContext::from(None, "foo bar".to_string());
warning.set_referent(ref_context.clone());
assert!(warning.has_referent());
assert_eq!(warning.get_referent(), Some(&ref_context.into()));
}
#[test]
fn unchanged_referent() {
let context = FullContext::from(None, "[[".to_string());
let ref_context = FullContext::from(None, "foo bar".to_string());
let warning = Warning::new(WarningKind::UnclosedLink, Some(context))
.with_referent(ref_context.clone());
assert_eq!(warning.get_referent(), Some(&ref_context.into()));
}
#[test]
#[cfg(feature = "issue-names")]
fn test_name() {
let context = FullContext::from(None, "[[".to_string());
let warning = Warning::new(WarningKind::UnclosedLink, Some(context));
assert_eq!(warning.get_name(), "UnclosedLink");
}
}