141 lines
4.2 KiB
Rust
141 lines
4.2 KiB
Rust
use std::{fmt::Debug, fs::{self, File}, io::{Read, Write}, path::PathBuf, str::FromStr, time::UNIX_EPOCH};
|
||
|
||
use log::info;
|
||
use ropey::Rope;
|
||
use serde::{Deserialize, Serialize};
|
||
use tower_lsp::lsp_types::*;
|
||
|
||
use crate::sources::LSPSupport;
|
||
|
||
use super::to_escape_path;
|
||
|
||
#[allow(unused)]
|
||
pub fn get_range_text(path: &PathBuf, range: &Range) -> Option<String> {
|
||
let path = to_escape_path(path);
|
||
if let Some(rope) = open_doc_as_rope(&path) {
|
||
let start_index = rope.pos_to_byte(&range.start);
|
||
let end_index = rope.pos_to_byte(&range.end);
|
||
info!("start index: {}, end index: {}", start_index, end_index);
|
||
return Some(rope.slice(start_index..end_index).to_string());
|
||
}
|
||
None
|
||
}
|
||
|
||
#[allow(unused)]
|
||
pub fn open_doc_as_rope(path: &PathBuf) -> Option<Rope> {
|
||
if let std::result::Result::Ok(text) = fs::read_to_string(path) {
|
||
let rope = Rope::from_str(text.as_str());
|
||
Some(rope)
|
||
} else {
|
||
None
|
||
}
|
||
}
|
||
|
||
pub struct RecursiveFileIterator {
|
||
stack: Vec<PathBuf>,
|
||
}
|
||
|
||
/// 递归获取所有文件
|
||
impl RecursiveFileIterator {
|
||
#[allow(unused)]
|
||
pub fn new(start_dir: &str) -> Self {
|
||
let start_dir = PathBuf::from_str(start_dir).unwrap();
|
||
RecursiveFileIterator {
|
||
stack: vec![start_dir],
|
||
}
|
||
}
|
||
}
|
||
|
||
impl Iterator for RecursiveFileIterator {
|
||
type Item = PathBuf;
|
||
fn next(&mut self) -> Option<Self::Item> {
|
||
while let Some(path) = self.stack.pop() {
|
||
if path.is_dir() {
|
||
if let Ok(entries) = fs::read_dir(path) {
|
||
for entry in entries.flatten() {
|
||
self.stack.push(entry.path());
|
||
}
|
||
}
|
||
} else {
|
||
return Some(path);
|
||
}
|
||
}
|
||
None
|
||
}
|
||
}
|
||
|
||
|
||
/// 计算文件大小,单位 KB
|
||
pub fn file_size_in_kb(path: &str) -> Result<u64, std::io::Error> {
|
||
// 获取文件元数据
|
||
let metadata = fs::metadata(path)?;
|
||
|
||
// 获取文件大小(以字节为单位)
|
||
let file_size_bytes = metadata.len();
|
||
|
||
// 将文件大小转换为 KB,并确保结果在 u32 范围内
|
||
let file_size_kb = (file_size_bytes / 1024) as u64;
|
||
|
||
Ok(file_size_kb)
|
||
}
|
||
|
||
pub fn get_last_modified_time(path: &str) -> Result<u64, std::io::Error> {
|
||
// 获取文件元数据
|
||
let metadata = fs::metadata(path)?;
|
||
|
||
// 获取文件的最近修改时间
|
||
let modified_time = metadata.modified()?;
|
||
|
||
let duration = modified_time.duration_since(UNIX_EPOCH).map_err(
|
||
|e| std::io::Error::new(std::io::ErrorKind::Other, e)
|
||
)?;
|
||
|
||
let seconds = duration.as_secs();
|
||
|
||
Ok(seconds)
|
||
}
|
||
|
||
/// 序列化结构体到二进制文件
|
||
pub fn k_serialize<T>(path: &PathBuf, data: T) -> Result<(), std::io::Error>
|
||
where T: Serialize + Debug {
|
||
let buffer: Vec<u8> = bincode::serialize(&data).unwrap();
|
||
match File::create(path) {
|
||
Ok(mut file) => {
|
||
match file.write_all(&buffer) {
|
||
Ok(_) => Ok(()),
|
||
Err(err) => Err(err)
|
||
}
|
||
}
|
||
Err(err) => Err(err)
|
||
}
|
||
}
|
||
|
||
/// 反序列化二进制文件到结构体
|
||
pub fn k_deserialize<T>(path: &PathBuf) -> Result<T, std::io::Error>
|
||
where T: for<'de> Deserialize<'de> + Debug {
|
||
match File::open(path) {
|
||
Ok(mut file) => {
|
||
let mut buffer = Vec::<u8>::new();
|
||
match file.read_to_end(&mut buffer) {
|
||
Ok(_) => {
|
||
let meta_map: Result<T, Box<bincode::ErrorKind>> = bincode::deserialize(&buffer);
|
||
if meta_map.is_ok() {
|
||
Ok(meta_map.unwrap())
|
||
} else {
|
||
let err: Box<bincode::ErrorKind> = meta_map.unwrap_err();
|
||
info!("error happen when deserialize index.cache from \"{path:?}\": {err:?}");
|
||
Err(std::io::Error::new(std::io::ErrorKind::InvalidData, err))
|
||
}
|
||
}
|
||
Err(err) => {
|
||
info!("error happen when load bytes to buffer from \"{path:?}\": {err:?}");
|
||
Err(err)
|
||
}
|
||
}
|
||
}
|
||
Err(err) => {
|
||
info!("error happen when read index.cache from \"{path:?}\": {err:?}");
|
||
Err(err)
|
||
}
|
||
}
|
||
} |