use crate::tarantool::tlua;
use crate::tarantool::tlua::PushGuard;
use crate::tarantool::tlua::{TuplePushError, Void};
use crate::tarantool::tuple::Encode;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::Arc;
#[macro_use]
pub mod http;
pub mod rpc;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Context {
data: HashMap<String, Arc<String>>,
}
impl Context {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Self {
data: HashMap::default(),
}
}
pub fn background() -> Self {
Self {
data: HashMap::from([(
"request_id".to_string(),
Arc::new(format!(
"background {}",
crate::tarantool::uuid::Uuid::random(),
)),
)]),
}
}
pub fn put(&mut self, key: impl Into<String>, value: impl Into<String>) {
self.data.insert(key.into(), Arc::new(value.into()));
}
pub fn get(&self, key: &str) -> Option<&str> {
self.data.get(key).map(|val| val.as_str())
}
pub fn endpoint_path(&self) -> &str {
self.data
.get("path")
.map(|s| s.as_str())
.unwrap_or("unknown")
}
pub fn enable_tracing(&mut self) {
self.put("tracing", "on")
}
pub fn tracing_enabled(&self) -> bool {
self.get("tracing").map(|v| v == "on").unwrap_or(false)
}
}
impl Encode for Context {}
impl<L> tlua::Push<L> for Context
where
L: tlua::AsLua + Debug,
{
type Err = TuplePushError<Void, TuplePushError<Void, Void>>;
fn push_to_lua(&self, lua: L) -> Result<PushGuard<L>, (Self::Err, L)> {
HashMap::from([(
"data",
self.data
.iter()
.map(|(k, v)| (k.as_str(), v.as_str()))
.collect::<HashMap<_, _>>(),
)])
.push_to_lua(lua)
}
}
impl<L> tlua::PushOne<L> for Context where L: tlua::AsLua + Debug {}
mod otel {
use super::Context;
use opentelemetry::propagation::{Extractor, Injector};
use opentelemetry::{global, Context as OTELContext};
impl Injector for Context {
fn set(&mut self, key: &str, value: String) {
self.put(key, value);
}
}
impl Extractor for Context {
fn get(&self, key: &str) -> Option<&str> {
self.get(key)
}
fn keys(&self) -> Vec<&str> {
self.data.keys().map(|k| k.as_str()).collect()
}
}
impl Context {
pub fn inject(&mut self, ctx: &OTELContext) {
global::get_text_map_propagator(|propagator| {
propagator.inject_context(ctx, self);
});
}
pub fn extract(&self) -> OTELContext {
global::get_text_map_propagator(|propagator| propagator.extract(self))
}
}
}