Skip to main content

anstyle_hyperlink/
hyperlink.rs

1/// Hyperlink formatter
2///
3/// # Example
4///
5/// ```
6/// let link = anstyle_hyperlink::Hyperlink::with_url("https://docs.rs/anstyle/latest/anstyle/");
7/// format!("Go to {link}anstyle's documentation{link:#}!");
8/// ```
9pub struct Hyperlink<D: core::fmt::Display> {
10    url: Option<D>,
11}
12
13impl<D: core::fmt::Display> Hyperlink<D> {
14    /// Directly create a hyperlink for a URL
15    ///
16    /// # Example
17    ///
18    /// ```
19    /// let link = anstyle_hyperlink::Hyperlink::with_url("https://docs.rs/anstyle/latest/anstyle/");
20    /// format!("Go to {link}anstyle's documentation{link:#}!");
21    /// ```
22    pub fn with_url(url: D) -> Self {
23        Self { url: Some(url) }
24    }
25}
26
27#[cfg(feature = "std")]
28impl Hyperlink<String> {
29    /// Create a hyperlink for a path
30    ///
31    /// # Example
32    ///
33    /// ```
34    /// let path = std::env::current_dir().unwrap();
35    /// let link = anstyle_hyperlink::Hyperlink::with_path(&path);
36    /// format!("Go to {link}CWD{link:#}!");
37    /// ```
38    #[cfg(feature = "file")]
39    pub fn with_path(path: &std::path::Path) -> Self {
40        let url = crate::path_to_url(path);
41        Self { url }
42    }
43}
44
45impl<D: core::fmt::Display> Default for Hyperlink<D> {
46    fn default() -> Self {
47        Self { url: None }
48    }
49}
50
51impl<D: core::fmt::Display> core::fmt::Display for Hyperlink<D> {
52    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53        let Some(url) = self.url.as_ref() else {
54            return Ok(());
55        };
56        if f.alternate() {
57            write!(f, "\x1B]8;;\x1B\\")
58        } else {
59            write!(f, "\x1B]8;;{url}\x1B\\")
60        }
61    }
62}