feat(desktop): add redis gui foundation baseline
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
238
crates/redis-core/src/connection.rs
Normal file
238
crates/redis-core/src/connection.rs
Normal file
@@ -0,0 +1,238 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::BackendError;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct ConnectionProfileDraft {
|
||||
pub display_name: String,
|
||||
pub target: ConnectionTarget,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct ConnectionTarget {
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
pub database: i64,
|
||||
pub username: Option<String>,
|
||||
pub tls_mode: TlsMode,
|
||||
}
|
||||
|
||||
impl Default for ConnectionTarget {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
host: "127.0.0.1".to_string(),
|
||||
port: 6379,
|
||||
database: 0,
|
||||
username: None,
|
||||
tls_mode: TlsMode::Disabled,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectionTarget {
|
||||
pub fn validate(&self) -> Result<(), BackendError> {
|
||||
if self.host.trim().is_empty() {
|
||||
return Err(BackendError::invalid_connection_config(
|
||||
"Redis host must not be empty.",
|
||||
));
|
||||
}
|
||||
|
||||
if self.database < 0 {
|
||||
return Err(BackendError::invalid_connection_config(
|
||||
"Redis database must be zero or a positive integer.",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisConnectionRequest {
|
||||
pub target: ConnectionTarget,
|
||||
pub password: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct ConnectionTestResult {
|
||||
pub selected_database: i64,
|
||||
pub authenticated_as: Option<String>,
|
||||
pub round_trip_status: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisCommandRequest {
|
||||
pub connection: RedisConnectionRequest,
|
||||
pub command: String,
|
||||
#[serde(default)]
|
||||
pub arguments: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct CommandExecutionResult {
|
||||
pub command: String,
|
||||
pub arguments: Vec<String>,
|
||||
pub database: i64,
|
||||
pub response: RedisResponse,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisKeyBrowseRequest {
|
||||
pub connection: RedisConnectionRequest,
|
||||
#[serde(default = "default_scan_cursor")]
|
||||
pub cursor: String,
|
||||
#[serde(default)]
|
||||
pub pattern: Option<String>,
|
||||
#[serde(default = "default_scan_page_size")]
|
||||
pub page_size: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisKeyBrowseResult {
|
||||
pub database: i64,
|
||||
pub submitted_cursor: String,
|
||||
pub next_cursor: String,
|
||||
pub has_more: bool,
|
||||
pub page_size: u32,
|
||||
pub pattern: Option<String>,
|
||||
pub keys: Vec<RedisKeyMetadata>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisKeyMetadataRequest {
|
||||
pub connection: RedisConnectionRequest,
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisValueReadRequest {
|
||||
pub connection: RedisConnectionRequest,
|
||||
pub key: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisValueWriteRequest {
|
||||
pub connection: RedisConnectionRequest,
|
||||
pub key: String,
|
||||
pub value: RedisValueWriteInput,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisKeyTtlUpdateRequest {
|
||||
pub connection: RedisConnectionRequest,
|
||||
pub key: String,
|
||||
pub operation: RedisKeyTtlUpdate,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisKeyMetadata {
|
||||
pub name: String,
|
||||
pub database: i64,
|
||||
pub exists: bool,
|
||||
pub key_type: String,
|
||||
pub ttl: RedisKeyTtl,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum RedisKeyTtl {
|
||||
Persistent,
|
||||
Missing,
|
||||
ExpiresInMillis { value: i64 },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisValueRecord {
|
||||
pub metadata: RedisKeyMetadata,
|
||||
pub data: RedisValueData,
|
||||
pub write_capability: RedisValueWriteCapability,
|
||||
pub ttl_write_supported: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisKeyTtlUpdateResult {
|
||||
pub metadata: RedisKeyMetadata,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisFieldValueEntry {
|
||||
pub field: RedisValueContent,
|
||||
pub value: RedisValueContent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisSortedSetEntry {
|
||||
pub member: RedisValueContent,
|
||||
pub score: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RedisStreamEntry {
|
||||
pub id: String,
|
||||
pub fields: Vec<RedisFieldValueEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum RedisValueContent {
|
||||
String { value: String },
|
||||
Binary { bytes: Vec<u8> },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum RedisValueData {
|
||||
Missing,
|
||||
String { value: RedisValueContent },
|
||||
Hash { entries: Vec<RedisFieldValueEntry> },
|
||||
List { items: Vec<RedisValueContent> },
|
||||
Set { members: Vec<RedisValueContent> },
|
||||
SortedSet { entries: Vec<RedisSortedSetEntry> },
|
||||
Stream { entries: Vec<RedisStreamEntry> },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum RedisValueWriteInput {
|
||||
String { value: String },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum RedisValueWriteCapability {
|
||||
None,
|
||||
ReplaceString,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum RedisKeyTtlUpdate {
|
||||
Persist,
|
||||
ExpiresInMillis { value: u64 },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum RedisResponse {
|
||||
Null,
|
||||
Integer { value: i64 },
|
||||
String { value: String },
|
||||
Binary { bytes: Vec<u8> },
|
||||
Array { items: Vec<RedisResponse> },
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TlsMode {
|
||||
Disabled,
|
||||
Preferred,
|
||||
Required,
|
||||
}
|
||||
|
||||
fn default_scan_cursor() -> String {
|
||||
"0".to_string()
|
||||
}
|
||||
|
||||
fn default_scan_page_size() -> u32 {
|
||||
100
|
||||
}
|
||||
Reference in New Issue
Block a user