chain.rs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. use crate::{
  2. config::PrfItem,
  3. utils::{dirs, help},
  4. };
  5. use serde_yaml::Mapping;
  6. use std::fs;
  7. #[derive(Debug, Clone)]
  8. pub struct ChainItem {
  9. pub uid: String,
  10. pub data: ChainType,
  11. }
  12. #[derive(Debug, Clone)]
  13. pub enum ChainType {
  14. Merge(Mapping),
  15. Script(String),
  16. }
  17. #[derive(Debug, Clone)]
  18. pub enum ChainSupport {
  19. Clash,
  20. ClashMeta,
  21. All,
  22. }
  23. impl From<&PrfItem> for Option<ChainItem> {
  24. fn from(item: &PrfItem) -> Self {
  25. let itype = item.itype.as_ref()?.as_str();
  26. let file = item.file.clone()?;
  27. let uid = item.uid.clone().unwrap_or("".into());
  28. let path = dirs::app_profiles_dir().ok()?.join(file);
  29. if !path.exists() {
  30. return None;
  31. }
  32. match itype {
  33. "script" => Some(ChainItem {
  34. uid,
  35. data: ChainType::Script(fs::read_to_string(path).ok()?),
  36. }),
  37. "merge" => Some(ChainItem {
  38. uid,
  39. data: ChainType::Merge(help::read_merge_mapping(&path).ok()?),
  40. }),
  41. _ => None,
  42. }
  43. }
  44. }
  45. impl ChainItem {
  46. /// 内建支持一些脚本
  47. pub fn builtin() -> Vec<(ChainSupport, ChainItem)> {
  48. // meta 的一些处理
  49. let meta_guard =
  50. ChainItem::to_script("verge_meta_guard", include_str!("./builtin/meta_guard.js"));
  51. // meta 1.13.2 alpn string 转 数组
  52. let hy_alpn =
  53. ChainItem::to_script("verge_hy_alpn", include_str!("./builtin/meta_hy_alpn.js"));
  54. vec![
  55. (ChainSupport::ClashMeta, hy_alpn),
  56. (ChainSupport::ClashMeta, meta_guard),
  57. ]
  58. }
  59. pub fn to_script<U: Into<String>, D: Into<String>>(uid: U, data: D) -> Self {
  60. Self {
  61. uid: uid.into(),
  62. data: ChainType::Script(data.into()),
  63. }
  64. }
  65. }
  66. impl ChainSupport {
  67. pub fn is_support(&self, core: Option<&String>) -> bool {
  68. match core {
  69. Some(core) => match (self, core.as_str()) {
  70. (ChainSupport::All, _) => true,
  71. (ChainSupport::Clash, "clash") => true,
  72. (ChainSupport::ClashMeta, "clash-meta") => true,
  73. _ => false,
  74. },
  75. None => true,
  76. }
  77. }
  78. }