1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! This module helps with ANSI strings

// These modules comes from https://github.com/Aloso/to-html/blob/main/crates/ansi-to-html
crate::using! {
    ansi,
    color
}

crate::using! {
    pub text,
    minifier
}

pub use ansi_to_html::Error;

fn invalid_ansi(s: &'static str) -> impl Fn() -> Error {
    move || Error::InvalidAnsi { msg: s.to_string() }
}

/// Represents an ANSI string.
///
/// They can be created using [From]: `AnsiString::from("ansi string")`
pub struct AnsiString(String);
impl From<String> for AnsiString {
    fn from(value: String) -> Self {
        Self(value)
    }
}
impl From<&str> for AnsiString {
    fn from(value: &str) -> Self {
        Self(value.to_owned())
    }
}
impl From<AnsiString> for String {
    fn from(value: AnsiString) -> Self {
        value.0
    }
}

impl AnsiString {
    pub fn as_ansi(&self) -> &str {
        &self.0
    }

    pub fn as_html(&self) -> Result<String, Error> {
        ansi_to_html::convert_with_opts(&self.0, &ansi_to_html::Opts::default())
    }

    pub fn as_plaintext(&self) -> String {
        strip_ansi_escapes::strip_str(&self.0)
    }

    pub fn as_styled_text(&self) -> Result<Vec<StyledText>, Error> {
        ansi_to_text(&self.0)
    }
}

#[cfg(feature = "graphql")]
#[async_graphql::Object]
/// Represents an ANSI string
impl AnsiString {
    /// ANSI representation of the string
    async fn ansi(&self) -> &str {
        self.as_ansi()
    }

    /// HTML representation of the string
    async fn html(&self) -> crate::error::GraphQLResult<String> {
        use crate::error::MapToErr;
        Ok(self.as_html().map_to_internal_err("Invalid ansi string")?)
    }

    /// Plain text representation of the string
    async fn plain(&self) -> String {
        self.as_plaintext()
    }

    /// Styled text representation of the string
    async fn text(&self) -> crate::error::GraphQLResult<Vec<StyledText>> {
        use crate::error::MapToErr;
        Ok(self.as_styled_text().map_to_internal_err("Invalid ansi string")?)
    }
}