#![allow(clippy::new_ret_no_self, clippy::unused_unit)]
use std::sync::Arc;
use ::id_effect::collections::hash_map;
use ::id_effect::{
Cap, CapabilityId, CapabilityKey, Env, FiberRef, ProviderBox, ProviderError, ProviderNode,
run_blocking,
};
use crate::{
CompositeLogBackend, EffectLogMinLevel, EffectLogger, LogLevel, install_composite_log_backend,
install_log_annotations_fiber_ref, install_log_spans_fiber_ref, install_min_log_level_fiber_ref,
};
#[derive(::id_effect::ProviderSpecDerive)]
#[provides(EffectLogger)]
pub struct EffectLoggerLive;
impl EffectLoggerLive {
fn new() -> EffectLogger {
EffectLogger
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[allow(dead_code)]
pub struct EffectLogMetadata;
#[derive(::id_effect::ProviderSpecDerive)]
#[provides(EffectLogMetadata)]
pub struct LogMetadataLive;
impl LogMetadataLive {
fn new() -> EffectLogMetadata {
let ann = run_blocking(
FiberRef::make_with(
hash_map::empty::<String, String>,
|m| m.clone(),
|p, _c| p.clone(),
),
(),
)
.expect("annotation FiberRef");
let sp = run_blocking(
FiberRef::make_with(Vec::<String>::new, |v| v.clone(), |p, _c| p.clone()),
(),
)
.expect("span FiberRef");
install_log_annotations_fiber_ref(ann);
install_log_spans_fiber_ref(sp);
EffectLogMetadata
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[allow(dead_code)]
pub struct EffectLogComposite;
#[inline]
pub fn provide_composite_logger(composite: Arc<CompositeLogBackend>) -> ProviderBox {
struct Node(Arc<CompositeLogBackend>);
impl ProviderNode for Node {
fn id(&self) -> &str {
"effect-logger-composite"
}
fn requires(&self) -> &[CapabilityId] {
&[]
}
fn provides(&self) -> CapabilityId {
Cap::<EffectLogComposite>::id()
}
fn cap_name(&self) -> &str {
"EffectLogComposite"
}
fn build(&self, deps: &Env) -> Result<Env, ProviderError> {
install_composite_log_backend(self.0.clone());
let mut out = deps.clone();
out.insert::<Cap<EffectLogComposite>>(EffectLogComposite);
Ok(out)
}
}
ProviderBox(Arc::new(Node(composite)))
}
#[inline]
pub fn provide_minimum_log_level(initial: LogLevel) -> ProviderBox {
struct Node(LogLevel);
impl ProviderNode for Node {
fn id(&self) -> &str {
"effect-logger-min-level"
}
fn requires(&self) -> &[CapabilityId] {
&[]
}
fn provides(&self) -> CapabilityId {
Cap::<EffectLogMinLevel>::id()
}
fn cap_name(&self) -> &str {
"EffectLogMinLevel"
}
fn build(&self, deps: &Env) -> Result<Env, ProviderError> {
let initial = self.0;
let fr = run_blocking(FiberRef::make(move || initial), ()).map_err(|e| ProviderError {
provider: "effect-logger-min-level",
message: format!("FiberRef::make: {e:?}"),
})?;
install_min_log_level_fiber_ref(fr.clone());
let mut out = deps.clone();
out.insert::<Cap<EffectLogMinLevel>>(fr);
Ok(out)
}
}
ProviderBox(Arc::new(Node(initial)))
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
#[test]
fn provide_composite_logger_installs_capability() {
let composite = Arc::new(CompositeLogBackend::new());
let node = provide_composite_logger(composite);
let env = node.0.build(&Env::new()).expect("build");
assert!(env.try_get::<Cap<EffectLogComposite>>().is_ok());
let logger_env = ProviderBox::new::<EffectLoggerLive>()
.0
.build(&Env::new())
.expect("logger live");
assert!(logger_env.try_get::<Cap<EffectLogger>>().is_ok());
let meta_env = ProviderBox::new::<LogMetadataLive>()
.0
.build(&Env::new())
.expect("metadata live");
assert!(meta_env.try_get::<Cap<EffectLogMetadata>>().is_ok());
}
#[test]
fn provide_minimum_log_level_installs_fiber_ref() {
let node = provide_minimum_log_level(LogLevel::Warn);
let env = node.0.build(&Env::new()).expect("build");
assert!(env.try_get::<Cap<EffectLogMinLevel>>().is_ok());
}
}