use super::code::Code;
use super::finding::Diagnostic;
use std::fmt;
#[derive(Clone, Debug)]
pub struct Findings(Vec<Diagnostic>);
impl Findings {
#[must_use]
pub fn code(&self) -> Option<Code> {
self.0.first().map(Diagnostic::code)
}
#[must_use]
pub fn as_slice(&self) -> &[Diagnostic] {
&self.0
}
#[must_use]
pub fn into_vec(self) -> Vec<Diagnostic> {
self.0
}
}
impl std::ops::Deref for Findings {
type Target = [Diagnostic];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> IntoIterator for &'a Findings {
type Item = &'a Diagnostic;
type IntoIter = std::slice::Iter<'a, Diagnostic>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl fmt::Display for Findings {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0.as_slice() {
[] => f.write_str("no findings"),
[only] => write!(f, "{only}"),
[first, rest @ ..] => write!(f, "{first} (and {} more)", rest.len()),
}
}
}
impl std::error::Error for Findings {}
impl From<Diagnostic> for Findings {
fn from(finding: Diagnostic) -> Self {
Self(vec![finding])
}
}
impl From<Vec<Diagnostic>> for Findings {
fn from(findings: Vec<Diagnostic>) -> Self {
Self(findings)
}
}
impl From<Findings> for Vec<Diagnostic> {
fn from(findings: Findings) -> Self {
findings.0
}
}
#[cfg(test)]
#[path = "findings_tests.rs"]
mod tests;