yazi_shared/scheme/
encode.rs1use std::fmt::{self, Display};
2
3use percent_encoding::{AsciiSet, CONTROLS, PercentEncode, percent_encode};
4
5use crate::{scheme::SchemeKind, url::Url};
6
7#[derive(Clone, Copy)]
8pub struct Encode<'a>(pub Url<'a>);
9
10impl<'a> From<crate::url::Encode<'a>> for Encode<'a> {
11 fn from(value: crate::url::Encode<'a>) -> Self { Self(value.0) }
12}
13
14impl<'a> Encode<'a> {
15 #[inline]
16 pub fn domain<'s>(s: &'s str) -> PercentEncode<'s> {
17 const SET: &AsciiSet = &CONTROLS.add(b'/').add(b':');
18 percent_encode(s.as_bytes(), SET)
19 }
20
21 pub(crate) fn ports(self) -> impl Display {
22 struct D<'a>(Encode<'a>);
23
24 impl Display for D<'_> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 macro_rules! w {
27 ($default_uri:expr, $default_urn:expr) => {{
28 let (uri, urn) = self.0.0.scheme().ports();
29 match (uri != $default_uri, urn != $default_urn) {
30 (true, true) => write!(f, ":{uri}:{urn}"),
31 (true, false) => write!(f, ":{uri}"),
32 (false, true) => write!(f, "::{urn}"),
33 (false, false) => Ok(()),
34 }
35 }};
36 }
37
38 match self.0.0.kind() {
39 SchemeKind::Regular => Ok(()),
40 SchemeKind::Search | SchemeKind::Archive => w!(0, 0),
41 SchemeKind::Sftp => {
42 w!(self.0.0.loc().name().is_some() as usize, self.0.0.loc().name().is_some() as usize)
43 }
44 }
45 }
46 }
47
48 D(self)
49 }
50}
51
52impl Display for Encode<'_> {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 match self.0 {
55 Url::Regular(_) => write!(f, "regular://"),
56 Url::Search { domain, .. } => write!(f, "search://{}{}/", Self::domain(domain), self.ports()),
57 Url::Archive { domain, .. } => {
58 write!(f, "archive://{}{}/", Self::domain(domain), self.ports())
59 }
60 Url::Sftp { domain, .. } => write!(f, "sftp://{}{}/", Self::domain(domain), self.ports()),
61 }
62 }
63}