use crate::config::Config; use anyhow::Result; use reqwest::header::HeaderMap; #[derive(Debug, Clone, Default, PartialEq)] pub struct Rate { pub up: u64, pub down: u64, } /// 根据clash info获取clash服务地址和请求头 pub fn clash_client_info() -> Result<(String, HeaderMap)> { let client = { Config::clash().data().get_client_info() }; let server = format!("http://{}", client.server); let mut headers = HeaderMap::new(); headers.insert("Content-Type", "application/json".parse()?); if let Some(secret) = client.secret { let secret = format!("Bearer {}", secret).parse()?; headers.insert("Authorization", secret); } Ok((server, headers)) } /// 缩短clash的日志 #[allow(dead_code)] pub fn parse_log(log: String) -> String { if log.starts_with("time=") && log.len() > 33 { return (log[33..]).to_owned(); } if log.len() > 9 { return (log[9..]).to_owned(); } log } #[allow(dead_code)] pub fn parse_check_output(log: String) -> String { let t = log.find("time="); let m = log.find("msg="); let mr = log.rfind('"'); if let (Some(_), Some(m), Some(mr)) = (t, m, mr) { let e = match log.find("level=error msg=") { Some(e) => e + 17, None => m + 5, }; if mr > m { return (log[e..mr]).to_owned(); } } let l = log.find("error="); let r = log.find("path=").or(Some(log.len())); if let (Some(l), Some(r)) = (l, r) { return (log[(l + 6)..(r - 1)]).to_owned(); } log } #[cfg(target_os = "macos")] pub fn get_traffic_ws_url() -> Result { let (url, _) = clash_client_info()?; let ws_url = url.replace("http://", "ws://") + "/traffic"; Ok(ws_url) } #[test] fn test_parse_check_output() { let str1 = r#"xxxx\n time="2022-11-18T20:42:58+08:00" level=error msg="proxy 0: 'alpn' expected type 'string', got unconvertible type '[]interface {}'""#; //let str2 = r#"20:43:49 ERR [Config] configuration file test failed error=proxy 0: unsupport proxy type: hysteria path=xxx"#; let str3 = r#" "time="2022-11-18T21:38:01+08:00" level=info msg="Start initial configuration in progress" time="2022-11-18T21:38:01+08:00" level=error msg="proxy 0: 'alpn' expected type 'string', got unconvertible type '[]interface {}'" configuration file xxx\n "#; let res1 = parse_check_output(str1.into()); // let res2 = parse_check_output(str2.into()); let res3 = parse_check_output(str3.into()); assert_eq!(res1, res3); }