pub mod record;
pub use record::{RecordedArg, RecordedRemark, RemarkArgValue, RemarkCollector};
use vize_l0::Span;
use super::{PassEvent, PassObserver};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum RemarkKind {
Applied,
Missed,
Analysis,
}
impl RemarkKind {
pub const ALL: [Self; 3] = [Self::Applied, Self::Missed, Self::Analysis];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Applied => "applied",
Self::Missed => "missed",
Self::Analysis => "analysis",
}
}
#[must_use]
pub fn from_name(name: &str) -> Option<Self> {
Self::ALL.into_iter().find(|kind| kind.as_str() == name)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RemarkValue<'a> {
Str(&'a str),
Int(i64),
Bool(bool),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RemarkArg<'a> {
pub key: &'static str,
pub value: RemarkValue<'a>,
}
impl<'a> RemarkArg<'a> {
#[must_use]
pub const fn str(key: &'static str, value: &'a str) -> Self {
Self {
key,
value: RemarkValue::Str(value),
}
}
#[must_use]
pub const fn int(key: &'static str, value: i64) -> Self {
Self {
key,
value: RemarkValue::Int(value),
}
}
#[must_use]
pub const fn bool(key: &'static str, value: bool) -> Self {
Self {
key,
value: RemarkValue::Bool(value),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Remark<'a> {
pub kind: RemarkKind,
pub name: &'static str,
pub span: Span,
pub args: &'a [RemarkArg<'a>],
}
impl<'a> Remark<'a> {
#[must_use]
pub const fn applied(name: &'static str, span: Span, args: &'a [RemarkArg<'a>]) -> Self {
Self {
kind: RemarkKind::Applied,
name,
span,
args,
}
}
#[must_use]
pub const fn missed(name: &'static str, span: Span, args: &'a [RemarkArg<'a>]) -> Self {
Self {
kind: RemarkKind::Missed,
name,
span,
args,
}
}
#[must_use]
pub const fn analysis(name: &'static str, span: Span, args: &'a [RemarkArg<'a>]) -> Self {
Self {
kind: RemarkKind::Analysis,
name,
span,
args,
}
}
}
pub trait RemarkSink {
const ENABLED: bool;
fn emit(&mut self, remark: &Remark<'_>);
#[inline]
#[must_use]
fn enabled(&self) -> bool {
Self::ENABLED
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct NoRemarks;
impl RemarkSink for NoRemarks {
const ENABLED: bool = false;
#[inline]
fn emit(&mut self, _remark: &Remark<'_>) {}
}
#[derive(Debug)]
pub struct PassRemarks<'r, 'p, O> {
observer: &'r mut O,
event: PassEvent<'p>,
}
impl<'r, 'p, O: PassObserver> PassRemarks<'r, 'p, O> {
pub(super) fn new(observer: &'r mut O, event: PassEvent<'p>) -> Self {
Self { observer, event }
}
#[must_use]
pub const fn event(&self) -> &PassEvent<'p> {
&self.event
}
}
impl<O: PassObserver> RemarkSink for PassRemarks<'_, '_, O> {
const ENABLED: bool = O::REMARKS;
#[inline]
fn emit(&mut self, remark: &Remark<'_>) {
if O::REMARKS {
self.observer.on_remark(&self.event, remark);
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct RemarkCounter {
pub applied: u32,
pub missed: u32,
pub analysis: u32,
}
impl RemarkCounter {
#[must_use]
pub const fn new() -> Self {
Self {
applied: 0,
missed: 0,
analysis: 0,
}
}
#[must_use]
pub const fn total(&self) -> u32 {
self.applied + self.missed + self.analysis
}
}
impl PassObserver for RemarkCounter {
const REMARKS: bool = true;
fn on_remark(&mut self, _event: &PassEvent<'_>, remark: &Remark<'_>) {
match remark.kind {
RemarkKind::Applied => self.applied += 1,
RemarkKind::Missed => self.missed += 1,
RemarkKind::Analysis => self.analysis += 1,
}
}
}