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)]
101pub enum JoinType {
102	Inner,
103	Left,
104}
105
106impl Default for JoinType {
107	fn default() -> Self {
108		JoinType::Left
109	}
110}
111
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
113pub enum IndexType {
114	Index,
115	Unique,
116	Primary,
117}
118
119impl Default for IndexType {
120	fn default() -> Self {
121		IndexType::Index
122	}
123}
124
125/// How a window is measured — either by time duration or by event count.
126#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
127pub enum WindowSize {
128	Duration(Duration),
129	Count(u64),
130}
131
132impl WindowSize {
133	pub fn is_count(&self) -> bool {
134		matches!(self, WindowSize::Count(_))
135	}
136
137	pub fn as_duration(&self) -> Option<Duration> {
138		match self {
139			WindowSize::Duration(d) => Some(*d),
140			_ => None,
141		}
142	}
143
144	pub fn as_count(&self) -> Option<u64> {
145		match self {
146			WindowSize::Count(c) => Some(*c),
147			_ => None,
148		}
149	}
150}
151
152/// A fully specified window kind. Each variant carries only the parameters
153/// that make sense for that kind.
154#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155pub enum WindowKind {
156	/// Fixed-size, non-overlapping windows.
157	/// Each event belongs to exactly one window.
158	Tumbling {
159		size: WindowSize,
160	},
161	/// Fixed-size, overlapping windows.
162	/// Each event can belong to multiple windows.
163	/// Invariant: slide < size, and both must be the same measure type.
164	Sliding {
165		size: WindowSize,
166		slide: WindowSize,
167	},
168	/// Continuously maintained window of the most recent N events
169	/// or most recent T duration. One window per group. Triggers every event.
170	Rolling {
171		size: WindowSize,
172	},
173	/// Gap-based window. Stays open while events arrive within `gap`.
174	/// Closes after `gap` duration of inactivity per group key.
175	Session {
176		gap: Duration,
177	},
178}
179
180impl WindowKind {
181	/// Returns the primary size measure for Tumbling, Sliding, and Rolling.
182	/// Returns None for Session (which uses gap instead).
183	pub fn size(&self) -> Option<&WindowSize> {
184		match self {
185			WindowKind::Tumbling {
186				size,
187			} => Some(size),
188			WindowKind::Sliding {
189				size,
190				..
191			} => Some(size),
192			WindowKind::Rolling {
193				size,
194			} => Some(size),
195			WindowKind::Session {
196				..
197			} => None,
198		}
199	}
200}