hx_lsp/
parser.rs

1use std::{collections::HashMap, fs::File, io::BufReader, path::PathBuf};
2
3use json_comments::StripComments;
4use serde::{Deserialize, Serialize, de::DeserializeOwned};
5use tracing::error;
6
7// use crate::Result;
8use anyhow::Result;
9
10pub trait Parser {
11    type Item: DeserializeOwned + Clone;
12    fn set_name(&mut self, name: String);
13    fn set_hasmap(&mut self, hs: HashMap<String, Self::Item>);
14}
15
16/// 解析 `code-snippets json` 文件
17pub fn parse<T>(lang_file_path: &PathBuf, name: String) -> Result<T>
18where
19    T: Parser + DeserializeOwned + Serialize + Clone + Default,
20{
21    let file = File::open(lang_file_path)?;
22    let reader = BufReader::new(file);
23
24    // 过滤注释内容
25    let json_data = StripComments::new(reader);
26
27    // 日志记录错误
28    let hs = match serde_json::from_reader(json_data) {
29        Ok(s) => s,
30        Err(err) => {
31            error!("{name} Parse Fail: {err:?}");
32            return Err(err.into());
33        }
34    };
35
36    let mut p: T = Default::default();
37    p.set_name(name);
38    p.set_hasmap(hs);
39
40    Ok(p)
41}
42
43/// `String` 或者 `Vec<String>`
44#[derive(Deserialize, Serialize, Clone, Debug)]
45#[serde(untagged)]
46pub enum StrOrSeq {
47    String(String),
48    Array(Vec<String>),
49}
50
51impl std::fmt::Display for StrOrSeq {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        write!(
54            f,
55            "{}",
56            match self {
57                StrOrSeq::String(s) => s.clone(),
58                StrOrSeq::Array(v) => v.join("\n"),
59            }
60        )
61    }
62}
63
64impl StrOrSeq {
65    /// 获取第一个元素
66    pub fn first(&self) -> Option<String> {
67        match self {
68            StrOrSeq::String(s) => Some(s.clone()),
69            StrOrSeq::Array(v) => v.first().cloned(),
70        }
71    }
72}