#![doc(html_logo_url = "https://raw.githubusercontent.com/emit-rs/emit/main/asset/logo.svg")]
#![deny(missing_docs)]
#![cfg_attr(not(test), no_std)]
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "alloc")]
extern crate alloc;
extern crate core;
pub mod and;
pub mod clock;
pub mod ctxt;
pub mod emitter;
pub mod empty;
pub mod event;
pub mod extent;
pub mod filter;
pub mod or;
pub mod path;
pub mod props;
pub mod rng;
pub mod runtime;
pub mod str;
pub mod template;
pub mod timestamp;
pub mod value;
pub mod well_known;
pub fn emit(
emitter: impl emitter::Emitter,
filter: impl filter::Filter,
ctxt: impl ctxt::Ctxt,
clock: impl clock::Clock,
evt: impl event::ToEvent,
) {
use self::{extent::ToExtent, props::Props};
ctxt.with_current(|ctxt| {
let evt = evt.to_event();
let extent = evt.extent().cloned().or_else(|| clock.now().to_extent());
let evt = evt
.with_extent(extent)
.map_props(|props| props.and_props(ctxt));
if filter.matches(&evt) {
emitter.emit(evt);
}
});
}
mod internal {
pub struct Erased<T>(pub(crate) T);
}
#[cfg(test)]
mod tests {
use super::*;
use std::{cell::Cell, time::Duration};
use crate::props::Props as _;
struct MyClock(Option<timestamp::Timestamp>);
impl clock::Clock for MyClock {
fn now(&self) -> Option<timestamp::Timestamp> {
self.0
}
}
struct MyCtxt(&'static str, usize);
impl ctxt::Ctxt for MyCtxt {
type Current = (&'static str, usize);
type Frame = ();
fn open_root<P: props::Props>(&self, _: P) -> Self::Frame {}
fn enter(&self, _: &mut Self::Frame) {}
fn exit(&self, _: &mut Self::Frame) {}
fn close(&self, _: Self::Frame) {}
fn with_current<R, F: FnOnce(&Self::Current) -> R>(&self, with: F) -> R {
with(&(self.0, self.1))
}
}
#[test]
fn emit_uses_clock_ctxt() {
let called = Cell::new(false);
emit(
emitter::from_fn(|evt| {
assert_eq!(13, evt.props().pull::<usize, _>("ctxt_prop").unwrap());
assert_eq!(true, evt.props().pull::<bool, _>("evt_prop").unwrap());
assert_eq!(
timestamp::Timestamp::from_unix(Duration::from_secs(77)).unwrap(),
evt.extent().unwrap().as_point()
);
called.set(true);
}),
empty::Empty,
MyCtxt("ctxt_prop", 13),
MyClock(timestamp::Timestamp::from_unix(Duration::from_secs(77))),
event::Event::new(
path::Path::new_unchecked("test"),
template::Template::literal("text"),
empty::Empty,
("evt_prop", true),
),
);
assert!(called.get());
}
#[test]
fn emit_uses_filter() {
emit(
emitter::from_fn(|_| panic!("filter should apply")),
filter::from_fn(|_| false),
empty::Empty,
empty::Empty,
event::Event::new(
path::Path::new_unchecked("test"),
template::Template::literal("text"),
empty::Empty,
("evt_prop", true),
),
);
}
}