2024-10-02 22:40:54 +08:00

141 lines
4.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}
}
}