1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
//! This library allows the creation of custom shotover transforms.
//!
//! There are two consumers of this library:
//! ## Custom Transforms
//!
//! To create a custom transform you need to implement these traits:
//! * [`transforms::TransformConfig`] - Defines what configuration fields the transform has in the `topology.yaml`.
//! * [`transforms::TransformBuilder`] - Defines how to build the Transform for a new incoming connection. Only one instance is created over shotovers runtime.
//! * [`transforms::Transform`] - Defines the transformation logic of the transform. A new instance is created per incoming connection.
//!
//! Simple transforms can implement all of these onto a single struct but generally you need seperate structs for each.
//!
//! ## The shotover binary
//! All custom transforms the user wants to use are statically compiled into a single binary.
//! The crate for this binary is very simple, it just consists of a `main.rs` like:
//!
//! ```no_run
//! # mod transform_crate {
//! # pub type TransformConfig = shotover::transforms::null::NullSinkConfig;
//! # }
//! shotover::import_transform!(transform_crate::TransformConfig);
//!
//! fn main() {
//! shotover::runner::Shotover::new().run_block();
//! }
//! ```
//!
// Accidentally printing would break json log output
#![deny(clippy::print_stdout)]
#![deny(clippy::print_stderr)]
#![allow(clippy::needless_doctest_main)]
#![allow(clippy::box_default)]
// Allow dead code if any of the protocol features are disabled
#![cfg_attr(
any(
not(feature = "cassandra"),
not(feature = "redis"),
not(feature = "kafka"),
not(feature = "opensearch"),
),
allow(dead_code, unused_imports, unused_variables, unused_mut)
)]
#[cfg(all(
not(feature = "cassandra"),
not(feature = "redis"),
not(feature = "kafka"),
not(feature = "opensearch"),
))]
compile_error!(
"At least one protocol feature must be enabled, e.g. `cassandra`, `redis`, `kafka` or `opensearch`"
);
pub mod codec;
pub mod config;
mod connection_span;
pub mod frame;
pub mod message;
mod observability;
pub mod runner;
mod server;
pub mod sources;
pub mod tcp;
pub mod tls;
mod tracing_panic_handler;
pub mod transforms;
/// Imports a custom transform into the shotover binary.
///
/// When a custom transform is defined in its own crate, typetag wont kick in unless there is some kind of `use crate_name::CustomTransformConfig`.
/// This macro does that for you while making it clear that the `use` is a little bit magic.
/// It also performs some type checks to ensure that you are actually importing an implementer of [`transforms::TransformConfig`].
#[macro_export]
macro_rules! import_transform {
($ty:ty) => {
// import the type, this is required for typetag to pick up the type
use $ty;
// assert that the type actually implements TransformConfig, this prevents the easy mistake of accidentally importing the Transform instead of the TransformConfig
const _: fn() = || {
// Only callable when `$ty` implements `TransformConfig`
fn assert_impls_transform_config<T: ?Sized + shotover::transforms::TransformConfig>() {}
assert_impls_transform_config::<$ty>();
};
};
}