#![recursion_limit = "256"]
pub mod adapter;
pub mod config;
pub mod embed;
pub mod handlers;
pub mod memory;
#[cfg(any(feature = "mem-probe", feature = "dhat-heap"))]
pub mod memprobe;
pub mod render;
pub mod rowmap;
pub mod sessions;
pub mod sql;
pub mod substrate;
pub mod transport;
pub mod wire;
pub const PROTOCOL_VERSION: u16 = 1;
use std::time::Duration;
use chrono::{DateTime, Utc};
use serde_json::Value;
pub trait Clock: Send + Sync {
fn now(&self) -> DateTime<Utc>;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct SystemClock;
impl Clock for SystemClock {
fn now(&self) -> DateTime<Utc> {
Utc::now()
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct RetryPolicy {
pub attempts: u8,
pub initial_backoff: Duration,
pub max_backoff: Duration,
pub jitter: f64,
}
impl Default for RetryPolicy {
fn default() -> Self {
Self {
attempts: 3,
initial_backoff: Duration::from_millis(300),
max_backoff: Duration::from_secs(5),
jitter: 0.2,
}
}
}
pub mod output {
use std::{
io::{self, IsTerminal, Write},
sync::OnceLock,
};
use anstyle::{AnsiColor, Style};
use anyhow::Context;
fn use_color() -> bool {
static USE: OnceLock<bool> = OnceLock::new();
*USE.get_or_init(|| std::env::var_os("NO_COLOR").is_none() && io::stdout().is_terminal())
}
pub fn paint(text: &str, style: Style) -> String {
if use_color() {
format!("{}{text}{}", style.render(), style.render_reset())
} else {
text.to_owned()
}
}
pub fn bold() -> Style {
Style::new().bold()
}
pub fn dim() -> Style {
Style::new().dimmed()
}
pub fn green() -> Style {
Style::new().fg_color(Some(AnsiColor::Green.into()))
}
pub fn yellow() -> Style {
Style::new().fg_color(Some(AnsiColor::Yellow.into()))
}
pub fn red() -> Style {
Style::new().fg_color(Some(AnsiColor::Red.into()))
}
pub fn cyan() -> Style {
Style::new().fg_color(Some(AnsiColor::Cyan.into()))
}
pub fn line(message: &str) -> anyhow::Result<()> {
let mut stdout = io::stdout().lock();
writeln!(stdout, "{message}")
.inspect_err(exit_if_broken_pipe)
.context("failed to write command output")
}
pub fn raw(bytes: &[u8]) -> anyhow::Result<()> {
let mut stdout = io::stdout().lock();
stdout
.write_all(bytes)
.and_then(|()| stdout.flush())
.inspect_err(exit_if_broken_pipe)
.context("failed to write command output")
}
pub fn exit_if_broken_pipe(error: &io::Error) {
if error.kind() == io::ErrorKind::BrokenPipe {
std::process::exit(0);
}
}
pub fn line_err(message: &str) -> anyhow::Result<()> {
let mut stderr = io::stderr().lock();
writeln!(stderr, "{message}")
.inspect_err(exit_if_broken_pipe)
.context("failed to write command meta")
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("validation failed: {message}")]
Validation {
message: String,
field: Option<String>,
value: Option<Value>,
expected: Option<String>,
},
#[error("not found: {message}")]
NotFound {
message: String,
kind: String,
pk: Value,
},
#[error("namespace unknown: {namespace}")]
NamespaceUnknown { namespace: String },
#[error("commit conflict after {attempts} attempt(s)")]
Conflict { attempts: u8 },
#[error("storage unavailable: {0}")]
Storage(#[from] anyhow::Error),
#[error("internal error: {0}")]
Internal(String),
}
impl Error {
pub fn validation(message: impl Into<String>) -> Self {
Self::Validation {
message: message.into(),
field: None,
value: None,
expected: None,
}
}
pub fn validation_field(
message: impl Into<String>,
field: impl Into<String>,
value: Option<Value>,
expected: Option<String>,
) -> Self {
Self::Validation {
message: message.into(),
field: Some(field.into()),
value,
expected,
}
}
pub fn not_found(kind: impl Into<String>, pk: Value, message: impl Into<String>) -> Self {
Self::NotFound {
message: message.into(),
kind: kind.into(),
pk,
}
}
pub fn namespace_unknown(namespace: impl Into<String>) -> Self {
Self::NamespaceUnknown {
namespace: namespace.into(),
}
}
pub fn conflict(attempts: u8) -> Self {
Self::Conflict { attempts }
}
pub fn internal(message: impl Into<String>) -> Self {
Self::Internal(message.into())
}
}
#[cfg(test)]
mod tests {
#![expect(clippy::expect_used, reason = "tests fail by panicking")]
use crate::adapter::test_support::{manifest_dir, rust_files};
#[test]
fn no_compile_time_checkout_path_reads() {
const PATH_VARS: [&str; 4] = [
"CARGO_MANIFEST_DIR",
"CARGO_MANIFEST_PATH",
"CARGO_BIN_EXE_",
"CARGO_TARGET_TMPDIR",
];
let root = manifest_dir();
let mut files = Vec::new();
for dir in ["src", "tests", "benches"] {
rust_files(&root.join(dir), &mut files);
}
let mut violations = Vec::new();
for path in &files {
let text = std::fs::read_to_string(path).expect("source is readable");
for (at, needle) in text.match_indices("env!(") {
let arg = text[at + needle.len()..].trim_start();
let reads_path = arg
.strip_prefix('"')
.is_some_and(|name| PATH_VARS.iter().any(|var| name.starts_with(var)));
if reads_path {
let line = text[..at].matches('\n').count() + 1;
let file = path.strip_prefix(&root).unwrap_or(path).display();
violations.push(format!("{file}:{line}"));
}
}
}
assert!(
violations.is_empty(),
"read these at runtime (`std::env::var_os`, a cwd-relative path, `pond_bin()`), \
never via `env!`/`option_env!`: {violations:#?}"
);
}
}