// ============ Redis 响应类型系统 ============
///|
/// Redis响应的基本类型
pub(all) enum RedisValue {
// 简单字符串: +OK\r\n
SimpleString(String)
// 错误: -ERR message\r\n
Error(String)
// 整数: :1000\r\n
Integer(Int)
// 批量字符串: $6\r\nfoobar\r\n 或 $-1\r\n (null)
BulkString(String?)
// 数组: *count\r\n...
Array(Array[RedisValue])
} derive(Debug, Hash, Eq)
///|
pub extend RedisValue with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend RedisValue with @moonbitlang/core/builtin.Hash::{hash, hash_combine}
///|
pub extend RedisValue with @moonbitlang/core/builtin.Eq::{equal, not_equal}
///|
pub extend RedisValue with Show::{output}
///|
pub impl Show for RedisValue with fn output(self, logger : &Logger) -> Unit {
logger.write_string(@debug.to_string(self))
}
///|
pub impl Show for RedisValue with fn to_string(self) -> String {
@debug.to_string(self)
}
///|
/// Redis命令的结果类型
pub type RedisResult[T] = Result[T, String]
///|
/// 常用的具体返回类型
pub type RedisString = RedisResult[String]
///|
pub type RedisJson = RedisResult[Json]
///|
pub type RedisBulkString = RedisResult[String?]
///|
pub type RedisInt = RedisResult[Int]
///|
pub type RedisBool = RedisResult[Bool]
///|
pub type RedisArray = RedisResult[Array[String]]
///|
pub type RedisHash = RedisResult[Map[String, String]]
///|
pub type RedisStreamResult = RedisResult[RedisStream]
///|
pub type RedisStreamMessageArray = RedisResult[Array[RedisStreamMessage]]
///|
pub(all) struct RedisStreamMessage {
id : String
fields : Array[String]
} derive(Debug)
///|
pub extend RedisStreamMessage with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend RedisStreamMessage with Show::{to_string, output}
///|
pub impl Show for RedisStreamMessage with fn output(
self : RedisStreamMessage,
logger : &Logger,
) -> Unit {
logger.write_string(@debug.to_string(self))
}
///|
pub impl Show for RedisStreamMessage with fn to_string(
self : RedisStreamMessage,
) -> String {
@debug.to_string(self)
}
///|
pub(all) struct RedisStream {
name : String
messages : Array[RedisStreamMessage]
} derive(Debug)
///|
pub extend RedisStream with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub extend RedisStream with Show::{to_string, output}
///|
pub impl Show for RedisStream with fn output(
self : RedisStream,
logger : &Logger,
) -> Unit {
logger.write_string(@debug.to_string(self))
}
///|
pub impl Show for RedisStream with fn to_string(self : RedisStream) -> String {
@debug.to_string(self)
}
///|
pub fn RedisValue::to_stream(self : RedisValue) -> RedisStreamResult {
match self {
Array(streams) =>
// Redis Stream 响应格式: [[stream_name, [[id, [field, value, ...]], ...]]]
match streams[0] {
Array(stream_data) =>
if stream_data.length() >= 2 {
let stream_name = match stream_data[0].to_string() {
Ok(name) => name
Err(_) => ""
}
let messages = match stream_data[1] {
Array(msg_array) => parse_stream_messages(msg_array)
_ => []
}
Ok({ name: stream_name, messages, })
} else {
Err("Invalid stream data: expected array with at least 2 elements")
}
_ => Err("Invalid stream data: expected array")
}
_ => Err("Invalid stream data: expected array")
}
}
///|
/// 解析 Stream 消息数组
fn parse_stream_messages(
msg_array : Array[RedisValue],
) -> Array[RedisStreamMessage] {
let messages = []
for msg in msg_array {
match msg {
Array(msg_data) =>
if msg_data.length() >= 2 {
let id = match msg_data[0].to_string() {
Ok(id_str) => id_str
Err(_) => ""
}
let fields = match msg_data[1] {
Array(field_array) => {
let field_strings = []
for field in field_array {
match field.to_string() {
Ok(field_str) => field_strings.push(field_str)
Err(_) => ()
}
}
field_strings
}
_ => []
}
messages.push({ id, fields, })
}
_ => ()
}
}
messages
}
///|
/// 将RedisValue转换为Stream消息数组(用于XRANGE等命令)
pub fn RedisValue::to_stream_message_array(
self : RedisValue,
) -> RedisStreamMessageArray {
match self {
Array(msg_array) => Ok(parse_stream_messages(msg_array))
_ => Err("Invalid stream message array")
}
}
///|
/// 将RedisValue转换为具体类型
pub fn RedisValue::to_bulk_string(self : RedisValue) -> RedisBulkString {
match self {
BulkString(Some(s)) => Ok(Some(s))
Error(e) => Err(e)
_ => Err("Type mismatch: expected string")
}
}
///|
/// 将RedisValue转换为具体类型
pub fn RedisValue::to_string(self : RedisValue) -> RedisString {
match self {
SimpleString(s) => Ok(s)
BulkString(Some(s)) => Ok(s)
Error(e) => Err(e)
_ => Err("Type mismatch: expected string")
}
}
///|
/// 将RedisValue转换为JSON
pub fn RedisValue::to_json(self : RedisValue) -> RedisJson {
self.to_string().map(s => @json.parse(s) catch { _ => Json::null() })
}
///|
/// 将RedisValue转换为整数
pub fn RedisValue::to_int(self : RedisValue) -> RedisInt {
match self {
Integer(i) => Ok(i)
Error(e) => Err(e)
_ => Err("Type mismatch: expected integer")
}
}
///|
/// 将RedisValue转换为布尔值
pub fn RedisValue::to_bool(self : RedisValue) -> RedisBool {
match self {
Integer(i) => Ok(i != 0)
SimpleString(s) => Ok(s == "OK")
Error(e) => Err(e)
_ => Err("Type mismatch: expected boolean")
}
}
///|
/// 将RedisValue转换为数组
pub fn RedisValue::to_array(self : RedisValue) -> RedisArray {
match self {
Array(arr) => Ok(arr.map(item => item.to_array_item_string()))
Error(e) => Err(e)
_ => Err("Type mismatch: expected array")
}
}
///|
fn RedisValue::to_array_item_string(self : RedisValue) -> String {
match self {
SimpleString(s) | BulkString(Some(s)) => s
BulkString(None) => "null"
Integer(i) => i.to_string()
Array(arr) => "[\{arr.map(item => item.to_array_item_string()).join(", ")}]"
Error(e) => "ERR \{e}"
}
}