Skip to main content

reifydb_sub_server/
wire.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::{collections::HashMap, sync::Arc};
5
6use reifydb_type::{
7	fragment::Fragment,
8	params::Params,
9	value::{
10		Value,
11		blob::Blob,
12		decimal::parse::parse_decimal,
13		identity::IdentityId,
14		temporal::parse::{
15			date::parse_date, datetime::parse_datetime, duration::parse_duration, time::parse_time,
16		},
17		uuid::parse::{parse_uuid4, parse_uuid7},
18	},
19};
20use serde::{Deserialize, Serialize};
21
22#[derive(Debug, Serialize, Deserialize)]
23pub struct WireValue {
24	#[serde(rename = "type")]
25	pub type_name: String,
26	pub value: String,
27}
28
29#[derive(Debug, Serialize, Deserialize)]
30#[serde(untagged)]
31pub enum WireParams {
32	Positional(Vec<WireValue>),
33	Named(HashMap<String, WireValue>),
34}
35
36fn wire_value_to_value(wire: WireValue) -> Result<Value, String> {
37	let v = wire.value.as_str();
38	match wire.type_name.as_str() {
39		"None" => Ok(Value::none()),
40		"Boolean" => v
41			.parse::<bool>()
42			.map(Value::Boolean)
43			.map_err(|e| format!("invalid Boolean value '{}': {}", v, e)),
44		"Float4" => {
45			v.parse::<f32>().map(Value::float4).map_err(|e| format!("invalid Float4 value '{}': {}", v, e))
46		}
47		"Float8" => {
48			v.parse::<f64>().map(Value::float8).map_err(|e| format!("invalid Float8 value '{}': {}", v, e))
49		}
50		"Int1" => v.parse::<i8>().map(Value::Int1).map_err(|e| format!("invalid Int1 value '{}': {}", v, e)),
51		"Int2" => v.parse::<i16>().map(Value::Int2).map_err(|e| format!("invalid Int2 value '{}': {}", v, e)),
52		"Int4" => v.parse::<i32>().map(Value::Int4).map_err(|e| format!("invalid Int4 value '{}': {}", v, e)),
53		"Int8" => v.parse::<i64>().map(Value::Int8).map_err(|e| format!("invalid Int8 value '{}': {}", v, e)),
54		"Int16" => {
55			v.parse::<i128>().map(Value::Int16).map_err(|e| format!("invalid Int16 value '{}': {}", v, e))
56		}
57		"Utf8" => Ok(Value::Utf8(v.to_string())),
58		"Uint1" => v.parse::<u8>().map(Value::Uint1).map_err(|e| format!("invalid Uint1 value '{}': {}", v, e)),
59		"Uint2" => {
60			v.parse::<u16>().map(Value::Uint2).map_err(|e| format!("invalid Uint2 value '{}': {}", v, e))
61		}
62		"Uint4" => {
63			v.parse::<u32>().map(Value::Uint4).map_err(|e| format!("invalid Uint4 value '{}': {}", v, e))
64		}
65		"Uint8" => {
66			v.parse::<u64>().map(Value::Uint8).map_err(|e| format!("invalid Uint8 value '{}': {}", v, e))
67		}
68		"Uint16" => {
69			v.parse::<u128>().map(Value::Uint16).map_err(|e| format!("invalid Uint16 value '{}': {}", v, e))
70		}
71		"Uuid4" => parse_uuid4(Fragment::internal(v))
72			.map(Value::Uuid4)
73			.map_err(|e| format!("invalid Uuid4 value '{}': {:?}", v, e)),
74		"Uuid7" => parse_uuid7(Fragment::internal(v))
75			.map(Value::Uuid7)
76			.map_err(|e| format!("invalid Uuid7 value '{}': {:?}", v, e)),
77		"Date" => parse_date(Fragment::internal(v))
78			.map(Value::Date)
79			.map_err(|e| format!("invalid Date value '{}': {:?}", v, e)),
80		"DateTime" => parse_datetime(Fragment::internal(v))
81			.map(Value::DateTime)
82			.map_err(|e| format!("invalid DateTime value '{}': {:?}", v, e)),
83		"Time" => parse_time(Fragment::internal(v))
84			.map(Value::Time)
85			.map_err(|e| format!("invalid Time value '{}': {:?}", v, e)),
86		"Duration" => parse_duration(Fragment::internal(v))
87			.map(Value::Duration)
88			.map_err(|e| format!("invalid Duration value '{}': {:?}", v, e)),
89		"Blob" => Blob::from_hex(Fragment::internal(v))
90			.map(Value::Blob)
91			.map_err(|e| format!("invalid Blob value '{}': {:?}", v, e)),
92		"Decimal" => parse_decimal(Fragment::internal(v))
93			.map(Value::Decimal)
94			.map_err(|e| format!("invalid Decimal value '{}': {:?}", v, e)),
95		"IdentityId" => parse_uuid7(Fragment::internal(v))
96			.map(|u| Value::IdentityId(IdentityId::new(u)))
97			.map_err(|e| format!("invalid IdentityId value '{}': {:?}", v, e)),
98		_ => Err(format!("unknown type '{}'", wire.type_name)),
99	}
100}
101
102impl WireParams {
103	pub fn into_params(self) -> Result<Params, String> {
104		match self {
105			WireParams::Positional(items) => {
106				let mut values = Vec::with_capacity(items.len());
107				for item in items {
108					values.push(wire_value_to_value(item)?);
109				}
110				Ok(Params::Positional(Arc::new(values)))
111			}
112			WireParams::Named(map) => {
113				let mut result = HashMap::with_capacity(map.len());
114				for (key, wire) in map {
115					result.insert(key, wire_value_to_value(wire)?);
116				}
117				Ok(Params::Named(Arc::new(result)))
118			}
119		}
120	}
121}