Watfaq / clash-rs

custom protocol network proxy
https://watfaq.gitbook.io/clashrs-user-manual/
Apache License 2.0
809 stars 64 forks source link

feat: compatiable with mihomo `icon` field #562

Closed greenhat616 closed 2 months ago

greenhat616 commented 2 months ago

🤔 This is a ...

🔗 Related issue link

Nope

💡 Background and solution

Mihomo introduce the icon field for showing a custom icon processed by GUI. Doc link: https://wiki.metacubex.one/config/proxy-groups/?h=icon#icon

What's more, it seems that:

📝 Changelog

☑️ Self-Check before Merge

⚠️ Please check all items below before requesting a reviewing. ⚠️

ibigbug commented 2 months ago

there is a CommonOptions https://github.com/Watfaq/clash-rs/blob/1391da4be8938eef641687f3fa20e8d0d675b50d/clash_lib/src/config/internal/proxy.rs#L128 but only on plain outbound, maybe add it to the groups too?

greenhat616 commented 2 months ago

there is a CommonOptions

https://github.com/Watfaq/clash-rs/blob/1391da4be8938eef641687f3fa20e8d0d675b50d/clash_lib/src/config/internal/proxy.rs#L128

but only on plain outbound, maybe add it to the groups too?

Oh, I missed this opts. I think I could do it later.

Additionaly, I think the handler opts could be merged into a share opts too.

ibigbug commented 2 months ago

some handlers has that too. they are pretty much the same which we can just pass down.

however on groups the connect_via is unsupported, but should be fine

greenhat616 commented 2 months ago

Yes. It chould be a huge refactor tweak to cleanup or redesign if possible.

Besides that, The OutboundType could be tweaked later. which approach do you think is better?

  1. use enumflags to create a sub matching group. It just put a derive macro and add extra methods. But it will use up to a u32 size. And, maybe we can use it refactor some config opts?
  2. use a nested type? maybe can use TryInto or other trait to make work?
  3. other approach?
ibigbug commented 2 months ago

yeah i agree. will look into it later, thanks!

re the enumflags2, I haven't thought much about it and I'm not so familia with the crate either - how would that change how the code looks like? do you have an example?

greenhat616 commented 2 months ago

yeah i agree. will look into it later, thanks!

re the enumflags2, I haven't thought much about it and I'm not so familia with the crate either - how would that change how the code looks like? do you have an example?

The behavior is similar to the crate bitflags, but is designed for enum.

It impl the equivalence of the iota in golang.

const (
    VERBOSE MyConf = 1 << iota
    CONFIG_FROM_DISK
    DATABASE_REQUIRED
    LOGGER_ACTIVATED
    DEBUG
    FLOAT_SUPPORT
    RECOVERY_MODE
    REBOOT_ON_FAILURE
)

The equivalence logic in enumflags:

use enumflags2::{bitflags, make_bitflags, BitFlags};

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum Test {
    VERBOSE,
    CONFIG_FROM_DISK,
    DATABASE_REQUIRED,
    LOGGER_ACTIVATED,
    DEBUG,
    FLOAT_SUPPORT,
    RECOVERY_MODE,
    REBOOT_ON_FAILURE,
}

And you can use it do the bitwise ops. And it provides candys.

Here is a usage in Nyanpasu:

use enumflags2::{bitflags, BitFlag, BitFlags};

#[bitflags]
#[repr(u8)]
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)]
pub enum ClashCore {
    #[serde(rename = "clash", alias = "clash-premium")]
    ClashPremium = 0b0001,
    #[serde(rename = "clash-rs")]
    ClashRs,
    #[serde(rename = "mihomo", alias = "clash-meta")]
    Mihomo,
    #[serde(rename = "mihomo-alpha")]
    MihomoAlpha,
}

/// a function return result:
pub fn builtin() -> Vec<(BitFlags<ClashCore>, ChainItem)> {
// ...

vec![
            (ClashCore::Mihomo | ClashCore::MihomoAlpha, hy_alpn),
            (ClashCore::Mihomo | ClashCore::MihomoAlpha, meta_guard),
            (ClashCore::all(), config_fixer),
            (ClashCore::ClashRs.into(), clash_rs_comp),
]
}

/// the final usage
 for item in ChainItem::builtin()
            .into_iter()
            .filter(|(s, _)| s.contains(*clash_core.as_ref().unwrap_or(&ClashCore::default()))) // This line is the bitflags judgement
            .map(|(_, c)| c)
{
  // ...
}

Ref: https://github.com/libnyanpasu/clash-nyanpasu/blob/f910c600878c281fd40c59c75f84fe6e32f4d968/backend/tauri/src/enhance/chain.rs#L133-L138, https://github.com/libnyanpasu/clash-nyanpasu/blob/f910c600878c281fd40c59c75f84fe6e32f4d968/backend/tauri/src/enhance/mod.rs#L118C8-L121C29

ibigbug commented 2 months ago

i see. thanks for the example. i think it has limited use case here and tbh I think it also adds extra costs to the readability

thoughts? @litcc @VendettaReborn

VendettaReborn commented 2 months ago

yeah, i agree, the benefit of enumflags2 is rather limited