1use 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)]
24pub struct WireValue {
25 #[serde(rename = "type")]
26 pub type_name: String,
27 pub value: String,
28}
29
30#[derive(Debug, Serialize, Deserialize)]
36#[serde(untagged)]
37pub enum WireParams {
38 Positional(Vec<WireValue>),
39 Named(HashMap<String, WireValue>),
40}
41
42fn wire_value_to_value(wire: WireValue) -> Result<Value, String> {
43 let v = wire.value.as_str();
44 match wire.type_name.as_str() {
45 "None" => Ok(Value::none()),
46 "Boolean" => v
47 .parse::<bool>()
48 .map(Value::Boolean)
49 .map_err(|e| format!("invalid Boolean value '{}': {}", v, e)),
50 "Float4" => {
51 v.parse::<f32>().map(Value::float4).map_err(|e| format!("invalid Float4 value '{}': {}", v, e))
52 }
53 "Float8" => {
54 v.parse::<f64>().map(Value::float8).map_err(|e| format!("invalid Float8 value '{}': {}", v, e))
55 }
56 "Int1" => v.parse::<i8>().map(Value::Int1).map_err(|e| format!("invalid Int1 value '{}': {}", v, e)),
57 "Int2" => v.parse::<i16>().map(Value::Int2).map_err(|e| format!("invalid Int2 value '{}': {}", v, e)),
58 "Int4" => v.parse::<i32>().map(Value::Int4).map_err(|e| format!("invalid Int4 value '{}': {}", v, e)),
59 "Int8" => v.parse::<i64>().map(Value::Int8).map_err(|e| format!("invalid Int8 value '{}': {}", v, e)),
60 "Int16" => {
61 v.parse::<i128>().map(Value::Int16).map_err(|e| format!("invalid Int16 value '{}': {}", v, e))
62 }
63 "Utf8" => Ok(Value::Utf8(v.to_string())),
64 "Uint1" => v.parse::<u8>().map(Value::Uint1).map_err(|e| format!("invalid Uint1 value '{}': {}", v, e)),
65 "Uint2" => {
66 v.parse::<u16>().map(Value::Uint2).map_err(|e| format!("invalid Uint2 value '{}': {}", v, e))
67 }
68 "Uint4" => {
69 v.parse::<u32>().map(Value::Uint4).map_err(|e| format!("invalid Uint4 value '{}': {}", v, e))
70 }
71 "Uint8" => {
72 v.parse::<u64>().map(Value::Uint8).map_err(|e| format!("invalid Uint8 value '{}': {}", v, e))
73 }
74 "Uint16" => {
75 v.parse::<u128>().map(Value::Uint16).map_err(|e| format!("invalid Uint16 value '{}': {}", v, e))
76 }
77 "Uuid4" => parse_uuid4(Fragment::internal(v))
78 .map(Value::Uuid4)
79 .map_err(|e| format!("invalid Uuid4 value '{}': {:?}", v, e)),
80 "Uuid7" => parse_uuid7(Fragment::internal(v))
81 .map(Value::Uuid7)
82 .map_err(|e| format!("invalid Uuid7 value '{}': {:?}", v, e)),
83 "Date" => parse_date(Fragment::internal(v))
84 .map(Value::Date)
85 .map_err(|e| format!("invalid Date value '{}': {:?}", v, e)),
86 "DateTime" => parse_datetime(Fragment::internal(v))
87 .map(Value::DateTime)
88 .map_err(|e| format!("invalid DateTime value '{}': {:?}", v, e)),
89 "Time" => parse_time(Fragment::internal(v))
90 .map(Value::Time)
91 .map_err(|e| format!("invalid Time value '{}': {:?}", v, e)),
92 "Duration" => parse_duration(Fragment::internal(v))
93 .map(Value::Duration)
94 .map_err(|e| format!("invalid Duration value '{}': {:?}", v, e)),
95 "Blob" => Blob::from_hex(Fragment::internal(v))
96 .map(Value::Blob)
97 .map_err(|e| format!("invalid Blob value '{}': {:?}", v, e)),
98 "Decimal" => parse_decimal(Fragment::internal(v))
99 .map(Value::Decimal)
100 .map_err(|e| format!("invalid Decimal value '{}': {:?}", v, e)),
101 "IdentityId" => parse_uuid7(Fragment::internal(v))
102 .map(|u| Value::IdentityId(IdentityId::new(u)))
103 .map_err(|e| format!("invalid IdentityId value '{}': {:?}", v, e)),
104 _ => Err(format!("unknown type '{}'", wire.type_name)),
105 }
106}
107
108impl WireParams {
109 pub fn into_params(self) -> Result<Params, String> {
110 match self {
111 WireParams::Positional(items) => {
112 let mut values = Vec::with_capacity(items.len());
113 for item in items {
114 values.push(wire_value_to_value(item)?);
115 }
116 Ok(Params::Positional(Arc::new(values)))
117 }
118 WireParams::Named(map) => {
119 let mut result = HashMap::with_capacity(map.len());
120 for (key, wire) in map {
121 result.insert(key, wire_value_to_value(wire)?);
122 }
123 Ok(Params::Named(Arc::new(result)))
124 }
125 }
126 }
127}