use serde::Serialize;
use std::io::Error;
use noop_handler::NoOpHandler;
#[cfg(feature = "full")]
use rustc_version_runtime::version;
#[cfg(feature = "full")]
use voidstar_handler::VoidstarHandler;
#[cfg(feature = "full")]
use local_handler::LocalHandler;
#[cfg(feature = "full")]
use once_cell::sync::Lazy;
mod noop_handler;
#[cfg(feature = "full")]
mod voidstar_handler;
#[cfg(feature = "full")]
mod local_handler;
#[derive(Serialize, Debug)]
struct AntithesisLanguageInfo {
name: &'static str,
version: String,
}
#[derive(Serialize, Debug)]
struct AntithesisVersionInfo {
language: AntithesisLanguageInfo,
sdk_version: &'static str,
protocol_version: &'static str,
}
#[derive(Serialize, Debug)]
struct AntithesisSDKInfo {
antithesis_sdk: AntithesisVersionInfo,
}
#[allow(dead_code)]
const PROTOCOL_VERSION: &str = "1.0.0";
#[allow(dead_code)]
const SDK_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const LOCAL_OUTPUT: &str = "ANTITHESIS_SDK_LOCAL_OUTPUT";
#[cfg(feature = "full")]
fn get_handler() -> Box<dyn LibHandler + Sync + Send> {
match VoidstarHandler::try_load() {
Ok(handler) => Box::new(handler),
Err(_) => match LocalHandler::new() {
Some(h) => Box::new(h),
None => Box::new(NoOpHandler::new()),
},
}
}
#[cfg(not(feature = "full"))]
#[allow(dead_code)]
fn get_handler() -> Box<dyn LibHandler + Sync + Send> {
Box::new(NoOpHandler::new())
}
#[cfg(feature = "full")]
pub(crate) static LIB_HANDLER: Lazy<Box<dyn LibHandler + Sync + Send>> = Lazy::new(|| {
let handler = get_handler();
let s = serde_json::to_string(&sdk_info()).unwrap_or("{}".to_owned());
let _ = handler.output(s.as_str());
handler
});
#[cfg(not(feature = "full"))]
pub(crate) static LIB_HANDLER: NoOpHandler = NoOpHandler{};
pub(crate) trait LibHandler {
fn output(&self, value: &str) -> Result<(), Error>;
fn random(&self) -> u64;
}
pub(crate) fn dispatch_random() -> u64 {
LIB_HANDLER.random()
}
pub fn dispatch_output<T: Serialize + ?Sized>(json_data: &T) {
let s = serde_json::to_string(json_data).unwrap_or("{}".to_owned());
let _ = LIB_HANDLER.output(s.as_str());
}
#[cfg(feature = "full")]
fn sdk_info() -> AntithesisSDKInfo {
let language_data = AntithesisLanguageInfo {
name: "Rust",
version: version().to_string(),
};
let version_data = AntithesisVersionInfo {
language: language_data,
sdk_version: SDK_VERSION,
protocol_version: PROTOCOL_VERSION,
};
AntithesisSDKInfo {
antithesis_sdk: version_data,
}
}