Skip to main content

reifydb_sub_server/
response.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::value::{Value, frame::frame::Frame, r#type::Type};
5use serde::{Deserialize, Serialize};
6
7/// A response frame containing query/command results.
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ResponseFrame {
10	pub row_numbers: Vec<u64>,
11	pub columns: Vec<ResponseColumn>,
12}
13
14/// A column in a response frame.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ResponseColumn {
17	pub name: String,
18	#[serde(rename = "type")]
19	pub r#type: Type,
20	pub data: Vec<String>,
21}
22
23/// Convert database result frames to response frames.
24///
25/// This function converts the internal `Frame` type to the serializable
26/// `ResponseFrame` type expected by clients.
27pub fn convert_frames(frames: Vec<Frame>) -> Vec<ResponseFrame> {
28	let mut result = Vec::new();
29
30	for frame in frames {
31		let row_numbers: Vec<u64> = frame.row_numbers.iter().map(|rn| rn.value()).collect();
32
33		let mut columns = Vec::new();
34
35		for column in frame.iter() {
36			let column_data: Vec<String> = column
37				.data
38				.iter()
39				.map(|value| match value {
40					Value::None {
41						..
42					} => "⟪none⟫".to_string(),
43					Value::Blob(b) => b.to_hex(),
44					_ => value.to_string(),
45				})
46				.collect();
47
48			columns.push(ResponseColumn {
49				name: column.name.clone(),
50				r#type: column.data.get_type(),
51				data: column_data,
52			});
53		}
54
55		result.push(ResponseFrame {
56			row_numbers,
57			columns,
58		});
59	}
60
61	result
62}