use crate::utils::trim_nul_end_str;
use crate::FastDFSError;
use std::fmt::{Debug, Display};
use std::hash::{Hash, Hasher};
use std::str::FromStr;
use std::time::SystemTime;
const SEPARATOR: &'static str = "/";
pub const TRACKER_DEFAULT_PORT: u16 = 22122;
pub const STORAGE_DEFAULT_PORT: u16 = 23000;
pub const FDFS_GROUP_NAME_MAX_LEN: usize = 16;
pub const FDFS_FILE_EXT_NAME_MAX_LEN: usize = 6;
pub const FDFS_MAX_META_NAME_LEN: usize = 64;
pub const FDFS_MAX_META_VALUE_LEN: usize = 256;
pub const FDFS_FILE_PREFIX_MAX_LEN: usize = 16;
pub const FDFS_STORAGE_ID_MAX_SIZE: usize = 16;
#[derive(PartialEq, PartialOrd, Eq, Ord, Clone)]
pub struct FileId {
pub group_name: String,
pub remote_filename: String,
}
impl Display for FileId {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}{SEPARATOR}{}", self.group_name, self.remote_filename)
}
}
impl Debug for FileId {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self)
}
}
impl Hash for FileId {
fn hash<H: Hasher>(&self, state: &mut H) {
state.write(self.group_name.as_bytes());
state.write(SEPARATOR.as_bytes());
state.write(self.remote_filename.as_bytes());
state.write_u8(0xff);
}
}
impl From<FileId> for String {
fn from(id: FileId) -> Self {
id.to_string()
}
}
impl<S0: AsRef<str>, S1: AsRef<str>> Into<FileId> for (S0, S1) {
fn into(self) -> FileId {
FileId {
group_name: self.0.as_ref().to_owned(),
remote_filename: self.1.as_ref().to_owned(),
}
}
}
impl FileId {
#[inline]
pub fn new<S0: AsRef<str>, S1: AsRef<str>>(group_name: S0, remote_filename: S1) -> Self {
(group_name, remote_filename).into()
}
}
impl FromStr for FileId {
type Err = FastDFSError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let file_id = trim_nul_end_str(s);
let Some(idx) = file_id.find(SEPARATOR) else {
return Err(FastDFSError::InvalidFileId(file_id.to_owned()));
};
if idx < 1 || idx >= file_id.len() - 1 || idx >= FDFS_GROUP_NAME_MAX_LEN {
return Err(FastDFSError::InvalidFileId(file_id.to_owned()));
}
Ok((&file_id[..idx], &file_id[idx + 1..]).into())
}
}
#[derive(Debug, Clone)]
pub struct FileInfo {
pub file_size: u64,
pub create_time: SystemTime,
pub crc32: u32,
pub source_ip_addr: String,
}
#[derive(Debug, Clone)]
pub struct StorageServer {
pub ip_addr: String,
pub port: u16,
pub store_path_index: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum StorageStatus {
Init = 0,
WaitSync = 1,
Syncing = 2,
IpChanged = 3,
Deleted = 4,
Offline = 5,
Online = 6,
Active = 7,
Recovery = 9,
None = 99,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum MetadataFlag {
Overwrite = b'O',
Merge = b'M',
}
impl From<MetadataFlag> for u8 {
fn from(flag: MetadataFlag) -> u8 {
flag as u8
}
}
#[derive(Debug, Clone)]
pub struct GroupStat {
pub group_name: String,
pub total_mb: u64,
pub free_mb: u64,
pub reserved_mb: u64,
pub trunk_free_mb: u64,
pub storage_count: u32,
pub storage_port: u32,
pub readable_server_count: u32,
pub writable_server_count: u32,
pub current_write_server: u32,
pub store_path_count: u32,
pub subdir_count_per_path: u32,
pub current_trunk_file_id: u32,
}
#[derive(Debug, Clone)]
pub struct StorageStat {
pub status: u8,
pub rw_mode: u8,
pub id: String,
pub ip_addr: String,
pub src_id: String,
pub version: String,
pub join_time: SystemTime,
pub up_time: SystemTime,
pub total_mb: u64,
pub free_mb: u64,
pub reserved_mb: u64,
pub upload_priority: u32,
pub store_path_count: u32,
pub subdir_count_per_path: u32,
pub storage_port: u32,
pub current_write_path: u32,
pub connection_alloc_count: u32,
pub connection_current_count: u32,
pub connection_max_count: u32,
pub total_upload_count: u64,
pub success_upload_count: u64,
pub total_append_count: u64,
pub success_append_count: u64,
pub total_modify_count: u64,
pub success_modify_count: u64,
pub total_truncate_count: u64,
pub success_truncate_count: u64,
pub total_set_meta_count: u64,
pub success_set_meta_count: u64,
pub total_delete_count: u64,
pub success_delete_count: u64,
pub total_download_count: u64,
pub success_download_count: u64,
pub total_get_meta_count: u64,
pub success_get_meta_count: u64,
pub total_create_link_count: u64,
pub success_create_link_count: u64,
pub total_delete_link_count: u64,
pub success_delete_link_count: u64,
pub total_upload_bytes: u64,
pub success_upload_bytes: u64,
pub total_append_bytes: u64,
pub success_append_bytes: u64,
pub total_modify_bytes: u64,
pub success_modify_bytes: u64,
pub total_download_bytes: u64,
pub success_download_bytes: u64,
pub total_sync_in_bytes: u64,
pub success_sync_in_bytes: u64,
pub total_sync_out_bytes: u64,
pub success_sync_out_bytes: u64,
pub total_file_open_count: u64,
pub success_file_open_count: u64,
pub total_file_read_count: u64,
pub success_file_read_count: u64,
pub total_file_write_count: u64,
pub success_file_write_count: u64,
pub last_source_update: SystemTime,
pub last_sync_update: SystemTime,
pub last_synced_timestamp: SystemTime,
pub last_heart_beat_time: SystemTime,
pub if_trunk_server: bool,
}
impl StorageStat {
pub fn status(&self) -> StorageStatus {
match self.status {
0 => StorageStatus::Init,
1 => StorageStatus::WaitSync,
2 => StorageStatus::Syncing,
3 => StorageStatus::IpChanged,
4 => StorageStatus::Deleted,
5 => StorageStatus::Offline,
6 => StorageStatus::Online,
7 => StorageStatus::Active,
9 => StorageStatus::Recovery,
_ => StorageStatus::None,
}
}
}
pub type Metadata = std::collections::HashMap<String, String>;
pub const FDFS_QUERY_FINFO_FLAGS_NOT_CALC_CRC32: u8 = 1;
pub const FDFS_QUERY_FINFO_FLAGS_KEEP_SILENCE: u8 = 2;