Skip to main content

reifydb_core/
common.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	fmt,
6	fmt::{Display, Formatter},
7	num::ParseIntError,
8	str::FromStr,
9	time::Duration,
10};
11
12use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Visitor};
13
14#[repr(transparent)]
15#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
16pub struct CommitVersion(pub u64);
17
18impl FromStr for CommitVersion {
19	type Err = ParseIntError;
20
21	fn from_str(s: &str) -> Result<Self, Self::Err> {
22		Ok(CommitVersion(u64::from_str(s)?))
23	}
24}
25
26impl Display for CommitVersion {
27	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
28		Display::fmt(&self.0, f)
29	}
30}
31
32impl PartialEq<i32> for CommitVersion {
33	fn eq(&self, other: &i32) -> bool {
34		self.0 == *other as u64
35	}
36}
37
38impl PartialEq<CommitVersion> for i32 {
39	fn eq(&self, other: &CommitVersion) -> bool {
40		*self as u64 == other.0
41	}
42}
43
44impl PartialEq<u64> for CommitVersion {
45	fn eq(&self, other: &u64) -> bool {
46		self.0.eq(other)
47	}
48}
49
50impl From<CommitVersion> for u64 {
51	fn from(value: CommitVersion) -> Self {
52		value.0
53	}
54}
55
56impl From<i32> for CommitVersion {
57	fn from(value: i32) -> Self {
58		Self(value as u64)
59	}
60}
61
62impl From<u64> for CommitVersion {
63	fn from(value: u64) -> Self {
64		Self(value)
65	}
66}
67
68impl Serialize for CommitVersion {
69	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70	where
71		S: Serializer,
72	{
73		serializer.serialize_u64(self.0)
74	}
75}
76
77impl<'de> Deserialize<'de> for CommitVersion {
78	fn deserialize<D>(deserializer: D) -> Result<CommitVersion, D::Error>
79	where
80		D: Deserializer<'de>,
81	{
82		struct U64Visitor;
83
84		impl Visitor<'_> for U64Visitor {
85			type Value = CommitVersion;
86
87			fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
88				formatter.write_str("an unsigned 64-bit number")
89			}
90
91			fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
92				Ok(CommitVersion(value))
93			}
94		}
95
96		deserializer.deserialize_u64(U64Visitor)
97	}
98}
99
100#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
101pub enum JoinType {
102	Inner,
103	#[default]
104	Left,
105}
106
107#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
108pub enum IndexType {
109	#[default]
110	Index,
111	Unique,
112	Primary,
113}
114
115/// How a window is measured — either by time duration or by event count.
116#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
117pub enum WindowSize {
118	Duration(Duration),
119	Count(u64),
120}
121
122impl WindowSize {
123	pub fn is_count(&self) -> bool {
124		matches!(self, WindowSize::Count(_))
125	}
126
127	pub fn as_duration(&self) -> Option<Duration> {
128		match self {
129			WindowSize::Duration(d) => Some(*d),
130			_ => None,
131		}
132	}
133
134	pub fn as_count(&self) -> Option<u64> {
135		match self {
136			WindowSize::Count(c) => Some(*c),
137			_ => None,
138		}
139	}
140}
141
142/// A fully specified window kind. Each variant carries only the parameters
143/// that make sense for that kind.
144#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
145pub enum WindowKind {
146	/// Fixed-size, non-overlapping windows.
147	/// Each event belongs to exactly one window.
148	Tumbling {
149		size: WindowSize,
150	},
151	/// Fixed-size, overlapping windows.
152	/// Each event can belong to multiple windows.
153	/// Invariant: slide < size, and both must be the same measure type.
154	Sliding {
155		size: WindowSize,
156		slide: WindowSize,
157	},
158	/// Continuously maintained window of the most recent N events
159	/// or most recent T duration. One window per group. Triggers every event.
160	Rolling {
161		size: WindowSize,
162	},
163	/// Gap-based window. Stays open while events arrive within `gap`.
164	/// Closes after `gap` duration of inactivity per group key.
165	Session {
166		gap: Duration,
167	},
168}
169
170impl WindowKind {
171	/// Returns the primary size measure for Tumbling, Sliding, and Rolling.
172	/// Returns None for Session (which uses gap instead).
173	pub fn size(&self) -> Option<&WindowSize> {
174		match self {
175			WindowKind::Tumbling {
176				size,
177			} => Some(size),
178			WindowKind::Sliding {
179				size,
180				..
181			} => Some(size),
182			WindowKind::Rolling {
183				size,
184			} => Some(size),
185			WindowKind::Session {
186				..
187			} => None,
188		}
189	}
190}