reifydb-core 0.4.12

Core database interfaces and data structures for ReifyDB
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 ReifyDB

use std::{
	fmt,
	fmt::{Display, Formatter},
	num::ParseIntError,
	str::FromStr,
	time::Duration,
};

use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Visitor};

#[repr(transparent)]
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
pub struct CommitVersion(pub u64);

impl FromStr for CommitVersion {
	type Err = ParseIntError;

	fn from_str(s: &str) -> Result<Self, Self::Err> {
		Ok(CommitVersion(u64::from_str(s)?))
	}
}

impl Display for CommitVersion {
	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
		Display::fmt(&self.0, f)
	}
}

impl PartialEq<i32> for CommitVersion {
	fn eq(&self, other: &i32) -> bool {
		self.0 == *other as u64
	}
}

impl PartialEq<CommitVersion> for i32 {
	fn eq(&self, other: &CommitVersion) -> bool {
		*self as u64 == other.0
	}
}

impl PartialEq<u64> for CommitVersion {
	fn eq(&self, other: &u64) -> bool {
		self.0.eq(other)
	}
}

impl From<CommitVersion> for u64 {
	fn from(value: CommitVersion) -> Self {
		value.0
	}
}

impl From<i32> for CommitVersion {
	fn from(value: i32) -> Self {
		Self(value as u64)
	}
}

impl From<u64> for CommitVersion {
	fn from(value: u64) -> Self {
		Self(value)
	}
}

impl Serialize for CommitVersion {
	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
	where
		S: Serializer,
	{
		serializer.serialize_u64(self.0)
	}
}

impl<'de> Deserialize<'de> for CommitVersion {
	fn deserialize<D>(deserializer: D) -> Result<CommitVersion, D::Error>
	where
		D: Deserializer<'de>,
	{
		struct U64Visitor;

		impl Visitor<'_> for U64Visitor {
			type Value = CommitVersion;

			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
				formatter.write_str("an unsigned 64-bit number")
			}

			fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
				Ok(CommitVersion(value))
			}
		}

		deserializer.deserialize_u64(U64Visitor)
	}
}

#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
pub enum JoinType {
	Inner,
	#[default]
	Left,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub enum IndexType {
	#[default]
	Index,
	Unique,
	Primary,
}

/// How a window is measured — either by time duration or by event count.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum WindowSize {
	Duration(Duration),
	Count(u64),
}

impl WindowSize {
	pub fn is_count(&self) -> bool {
		matches!(self, WindowSize::Count(_))
	}

	pub fn as_duration(&self) -> Option<Duration> {
		match self {
			WindowSize::Duration(d) => Some(*d),
			_ => None,
		}
	}

	pub fn as_count(&self) -> Option<u64> {
		match self {
			WindowSize::Count(c) => Some(*c),
			_ => None,
		}
	}
}

/// A fully specified window kind. Each variant carries only the parameters
/// that make sense for that kind.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum WindowKind {
	/// Fixed-size, non-overlapping windows.
	/// Each event belongs to exactly one window.
	Tumbling {
		size: WindowSize,
	},
	/// Fixed-size, overlapping windows.
	/// Each event can belong to multiple windows.
	/// Invariant: slide < size, and both must be the same measure type.
	Sliding {
		size: WindowSize,
		slide: WindowSize,
	},
	/// Continuously maintained window of the most recent N events
	/// or most recent T duration. One window per group. Triggers every event.
	Rolling {
		size: WindowSize,
	},
	/// Gap-based window. Stays open while events arrive within `gap`.
	/// Closes after `gap` duration of inactivity per group key.
	Session {
		gap: Duration,
	},
}

impl WindowKind {
	/// Returns the primary size measure for Tumbling, Sliding, and Rolling.
	/// Returns None for Session (which uses gap instead).
	pub fn size(&self) -> Option<&WindowSize> {
		match self {
			WindowKind::Tumbling {
				size,
			} => Some(size),
			WindowKind::Sliding {
				size,
				..
			} => Some(size),
			WindowKind::Rolling {
				size,
			} => Some(size),
			WindowKind::Session {
				..
			} => None,
		}
	}
}