use crate::error::{QuickDbError, QuickDbResult};
use crate::types::DataValue;
use rat_logger::{debug, error, info, warn};
use serde::{Deserialize, Serialize};
use serde_json::{Map as JsonMap, Value as JsonValue};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OutputFormat {
JsonString,
JsonObject,
RawData,
}
impl Default for OutputFormat {
fn default() -> Self {
OutputFormat::JsonString
}
}
#[derive(Debug, Clone)]
pub struct SerializerConfig {
pub format: OutputFormat,
pub pretty: bool,
pub include_null: bool,
pub datetime_format: Option<String>,
pub float_precision: Option<usize>,
}
impl Default for SerializerConfig {
fn default() -> Self {
Self {
format: OutputFormat::JsonString,
pretty: false,
include_null: true,
datetime_format: None,
float_precision: None,
}
}
}
impl SerializerConfig {
pub fn new() -> Self {
Self::default()
}
pub fn format(mut self, format: OutputFormat) -> Self {
self.format = format;
self
}
pub fn pretty(mut self, pretty: bool) -> Self {
self.pretty = pretty;
self
}
pub fn include_null(mut self, include_null: bool) -> Self {
self.include_null = include_null;
self
}
pub fn datetime_format(mut self, format: &str) -> Self {
self.datetime_format = Some(format.to_string());
self
}
pub fn float_precision(mut self, precision: usize) -> Self {
self.float_precision = Some(precision);
self
}
pub fn for_pyo3() -> Self {
Self {
format: OutputFormat::JsonString,
pretty: false,
include_null: true,
datetime_format: Some("%Y-%m-%dT%H:%M:%S%.3fZ".to_string()),
float_precision: Some(6),
}
}
pub fn for_rust() -> Self {
Self {
format: OutputFormat::JsonObject,
pretty: false,
include_null: false,
datetime_format: None,
float_precision: None,
}
}
pub fn for_debug() -> Self {
Self {
format: OutputFormat::JsonString,
pretty: true,
include_null: true,
datetime_format: Some("%Y-%m-%d %H:%M:%S".to_string()),
float_precision: Some(2),
}
}
}
#[derive(Debug, Clone)]
pub enum SerializationResult {
JsonString(String),
JsonObject(JsonValue),
RawData(HashMap<String, DataValue>),
}
impl SerializationResult {
pub fn to_json_string(&self) -> QuickDbResult<String> {
match self {
SerializationResult::JsonString(s) => Ok(s.clone()),
SerializationResult::JsonObject(obj) => {
serde_json::to_string(obj).map_err(|e| QuickDbError::SerializationError {
message: format!("序列化为JSON字符串失败: {}", e),
})
}
SerializationResult::RawData(data) => {
let json_obj = data_map_to_json_value(data)?;
serde_json::to_string(&json_obj).map_err(|e| QuickDbError::SerializationError {
message: format!("序列化为JSON字符串失败: {}", e),
})
}
}
}
pub fn to_json_object(&self) -> QuickDbResult<JsonValue> {
match self {
SerializationResult::JsonString(s) => {
serde_json::from_str(s).map_err(|e| QuickDbError::SerializationError {
message: format!("解析JSON字符串失败: {}", e),
})
}
SerializationResult::JsonObject(obj) => Ok(obj.clone()),
SerializationResult::RawData(data) => data_map_to_json_value(data),
}
}
pub fn to_raw_data(&self) -> QuickDbResult<HashMap<String, DataValue>> {
match self {
SerializationResult::JsonString(s) => {
let json_obj: JsonValue =
serde_json::from_str(s).map_err(|e| QuickDbError::SerializationError {
message: format!("解析JSON字符串失败: {}", e),
})?;
json_value_to_data_map(&json_obj)
}
SerializationResult::JsonObject(obj) => json_value_to_data_map(obj),
SerializationResult::RawData(data) => Ok(data.clone()),
}
}
pub fn result_type(&self) -> &'static str {
match self {
SerializationResult::JsonString(_) => "json_string",
SerializationResult::JsonObject(_) => "json_object",
SerializationResult::RawData(_) => "raw_data",
}
}
}
pub struct DataSerializer {
config: SerializerConfig,
}
impl DataSerializer {
pub fn new(config: SerializerConfig) -> Self {
debug!("创建数据序列化器: format={:?}", config.format);
Self { config }
}
pub fn default() -> Self {
Self::new(SerializerConfig::default())
}
pub fn serialize_record(
&self,
data: HashMap<String, DataValue>,
) -> QuickDbResult<SerializationResult> {
debug!("序列化单个记录: {} 个字段", data.len());
let processed_data = self.process_data(data)?;
match self.config.format {
OutputFormat::JsonString => {
let json_obj = data_map_to_json_value(&processed_data)?;
let json_str = if self.config.pretty {
serde_json::to_string_pretty(&json_obj)
} else {
serde_json::to_string(&json_obj)
}
.map_err(|e| QuickDbError::SerializationError {
message: format!("序列化失败: {}", e),
})?;
Ok(SerializationResult::JsonString(json_str))
}
OutputFormat::JsonObject => {
let json_obj = data_map_to_json_value(&processed_data)?;
Ok(SerializationResult::JsonObject(json_obj))
}
OutputFormat::RawData => Ok(SerializationResult::RawData(processed_data)),
}
}
pub fn serialize_records(
&self,
records: Vec<HashMap<String, DataValue>>,
) -> QuickDbResult<SerializationResult> {
debug!("序列化多个记录: {} 条记录", records.len());
let mut processed_records = Vec::new();
for record in records {
let processed_data = self.process_data(record)?;
processed_records.push(processed_data);
}
match self.config.format {
OutputFormat::JsonString => {
let mut json_array = Vec::new();
for record in processed_records {
let json_obj = data_map_to_json_value(&record)?;
json_array.push(json_obj);
}
let json_str = if self.config.pretty {
serde_json::to_string_pretty(&json_array)
} else {
serde_json::to_string(&json_array)
}
.map_err(|e| QuickDbError::SerializationError {
message: format!("序列化失败: {}", e),
})?;
Ok(SerializationResult::JsonString(json_str))
}
OutputFormat::JsonObject => {
let mut json_array = Vec::new();
for record in processed_records {
let json_obj = data_map_to_json_value(&record)?;
json_array.push(json_obj);
}
Ok(SerializationResult::JsonObject(JsonValue::Array(
json_array,
)))
}
OutputFormat::RawData => {
let mut result_data = HashMap::new();
result_data.insert(
"records".to_string(),
DataValue::Array(
processed_records
.into_iter()
.map(|record| DataValue::Object(record))
.collect(),
),
);
Ok(SerializationResult::RawData(result_data))
}
}
}
pub fn serialize_query_result(
&self,
records: Vec<HashMap<String, DataValue>>,
total_count: Option<u64>,
has_more: Option<bool>,
) -> QuickDbResult<SerializationResult> {
debug!("序列化查询结果: {} 条记录", records.len());
let mut result_data = HashMap::new();
let records_result = self.serialize_records(records)?;
match records_result {
SerializationResult::JsonObject(JsonValue::Array(arr)) => {
result_data.insert(
"data".to_string(),
DataValue::Array(arr.into_iter().map(|v| DataValue::from_json(v)).collect()),
);
}
SerializationResult::RawData(raw) => {
if let Some(DataValue::Array(records)) = raw.get("records") {
result_data.insert("data".to_string(), DataValue::Array(records.clone()));
}
}
_ => {
return Err(QuickDbError::SerializationError {
message: "无法处理记录序列化结果".to_string(),
});
}
}
if let Some(count) = total_count {
result_data.insert("total_count".to_string(), DataValue::Int(count as i64));
}
if let Some(more) = has_more {
result_data.insert("has_more".to_string(), DataValue::Bool(more));
}
result_data.insert(
"count".to_string(),
DataValue::Int(
if let Some(DataValue::Array(data)) = result_data.get("data") {
data.len() as i64
} else {
0
},
),
);
match self.config.format {
OutputFormat::JsonString => {
let json_obj = data_map_to_json_value(&result_data)?;
let json_str = if self.config.pretty {
serde_json::to_string_pretty(&json_obj)
} else {
serde_json::to_string(&json_obj)
}
.map_err(|e| QuickDbError::SerializationError {
message: format!("序列化失败: {}", e),
})?;
Ok(SerializationResult::JsonString(json_str))
}
OutputFormat::JsonObject => {
let json_obj = data_map_to_json_value(&result_data)?;
Ok(SerializationResult::JsonObject(json_obj))
}
OutputFormat::RawData => Ok(SerializationResult::RawData(result_data)),
}
}
fn process_data(
&self,
mut data: HashMap<String, DataValue>,
) -> QuickDbResult<HashMap<String, DataValue>> {
if !self.config.include_null {
data.retain(|_, v| !matches!(v, DataValue::Null));
}
if let Some(ref format) = self.config.datetime_format {
for (_, value) in data.iter_mut() {
if let DataValue::DateTime(dt) = value {
}
}
}
if let Some(precision) = self.config.float_precision {
for (_, value) in data.iter_mut() {
if let DataValue::Float(f) = value {
let multiplier = 10_f64.powi(precision as i32);
*f = (*f * multiplier).round() / multiplier;
}
}
}
Ok(data)
}
}
fn data_map_to_json_value(data: &HashMap<String, DataValue>) -> QuickDbResult<JsonValue> {
let mut json_map = JsonMap::new();
for (key, value) in data {
json_map.insert(key.clone(), value.to_json_value());
}
Ok(JsonValue::Object(json_map))
}
fn json_value_to_data_map(json: &JsonValue) -> QuickDbResult<HashMap<String, DataValue>> {
let mut data_map = HashMap::new();
if let JsonValue::Object(obj) = json {
for (key, value) in obj {
data_map.insert(key.clone(), DataValue::from_json_value(value.clone()));
}
} else {
return Err(QuickDbError::SerializationError {
message: "JSON值不是对象类型".to_string(),
});
}
Ok(data_map)
}
static DEFAULT_SERIALIZER: once_cell::sync::Lazy<DataSerializer> =
once_cell::sync::Lazy::new(|| DataSerializer::default());
static RUST_SERIALIZER: once_cell::sync::Lazy<DataSerializer> =
once_cell::sync::Lazy::new(|| DataSerializer::new(SerializerConfig::for_rust()));
pub fn serialize_record(data: HashMap<String, DataValue>) -> QuickDbResult<String> {
let result = DEFAULT_SERIALIZER.serialize_record(data)?;
result.to_json_string()
}
pub fn serialize_records(records: Vec<HashMap<String, DataValue>>) -> QuickDbResult<String> {
let result = DEFAULT_SERIALIZER.serialize_records(records)?;
result.to_json_string()
}
pub fn serialize_record_for_rust(data: HashMap<String, DataValue>) -> QuickDbResult<JsonValue> {
let result = RUST_SERIALIZER.serialize_record(data)?;
result.to_json_object()
}
pub fn serialize_records_for_rust(
records: Vec<HashMap<String, DataValue>>,
) -> QuickDbResult<JsonValue> {
let result = RUST_SERIALIZER.serialize_records(records)?;
result.to_json_object()
}
pub fn serialize_query_result(
records: Vec<HashMap<String, DataValue>>,
total_count: Option<u64>,
has_more: Option<bool>,
) -> QuickDbResult<String> {
let result = DEFAULT_SERIALIZER.serialize_query_result(records, total_count, has_more)?;
result.to_json_string()
}
pub fn serialize_query_result_for_rust(
records: Vec<HashMap<String, DataValue>>,
total_count: Option<u64>,
has_more: Option<bool>,
) -> QuickDbResult<JsonValue> {
let result = RUST_SERIALIZER.serialize_query_result(records, total_count, has_more)?;
result.to_json_object()
}